Python基础教程第九章--------多么痛的领悟
来源:互联网 发布:mysql视频教程 百度云 编辑:程序博客网 时间:2024/06/06 03:58
前面看的还算顺利吧,到了这章不知道怎么回事,忽然卡壳,十几页的书我足足看了一天,到现在也不是太明白。可能是对对象,类,多态这些面向对象的东西还不怎么清楚的原因吧。话不多说,分享一下我的经验给那些和我一样苦恼的人。
1、碎碎念:
__metaclass__= type 放在模块的最开始,表示你使用的是新式类,有些方法只有新式类才可以用,比如supper。
一般来说,只要我们定义了一个类,比如:
class test(){}
可能在你看来这个类没有继承其他类,因为类名后面的括号内没有任何东西,但是,在创建test的时候我们还是隐式的继承了object这个内建类。可以说,python中自己定义的所有的类都是它的子类,它是所有类的基类。
python3.x中已经没有了“旧类”的概念,但是在之前的版本还依然存在。
2、关于“魔法方法”
__init__ 构造函数
__del__ 析构函数
在子类中,继承了父类中所有的方法。如果父类中的方法并不满足我们子类当中的某些使用条件,那么我们就要“重写”类的一些方法。这其中有比较特殊的就是构造函数: 如果要在子类中重写构造函数,那么在子类的构造函数中在对自己类的初始化的同时也要调用父类的构造函数。因为,如果子类当中要使用一些父类中的属性,很可能因为没有初始化父类而导致使用的错误,因为没有初始化的变量被引用是不被允许的。
class bird():def __init__(self):self.a = 0class bird_1(bird):def __init__(self):bird.__init__(self)self.sound = "haha"这里为了调用父类的构造函数,用到了未绑定的父类的构造方法。
绑定方法:即用对象。方法的形式来调用,每个方法都有一个self参数指向调用他的对象,在对象引用这个方法的时候,该方法就绑定到了这个对象上。
非绑定方法:因为方法的定义是在类中,也就是说,该方法的命名空间是类域。那么用命名空间。方法的形式去调用一个方法显然是不绑定任何对象的,但是这样一来我们就要为这个方法显式的制定self参数,不然它不会知道要对哪个对象的特性进行操作
除了利用非绑定方法来调用父类中的构造函数意外,在新类中,还可以用supper函数来实现这个功能
supper():
当前子类和对象都可以作为supper的函数来调用,该函数会返回一个supper对象,再次之后再调用任何方法和特性,都是针对该类的所有父类进行搜寻要调用的特性。
class bird():def __init__(self):self.a = 0class bird_1(bird):def __init__(self):supper(bird_1, self).__init__()self.sound = "haha"
其实序列和字典这些python的内建类型所使用的方法都是所谓的“魔法方法”,这些方法都是python在内部定义过的。一个统一的格式应该是方法名前后都有两个下划线吧。比如在列表这个内建类型中,如果相求一个列表的元素个数,应该用的是len(a).此时的这个len函数就是魔法函数中的__len__(self).
如果自己想定义一个特殊的类型,而大部分的特性又和列表相关,那么就可以用继承的方式,省去实现很多系统中早已经定义好的方法
访问器方法实际上就是在访问类中特性的同时还要对特性做一些操作的方法,并且在封装和私有化上有着不小的作用(python中没有真正的私有化)
为了让代码写的更加简洁一点,便不会再类中定义了很多构造函数来满足特性的访问和修改的工作,而是用一种叫做访问器隐藏的方法========Property
property:
这个函数会生成一个属性,将访问器函数作为参数。
class test(){def __init__(self):self.name=""self.age=0def get_num(self):return self.name, self.agedef set_num(self, size):self.name, self.age = sizesize = property(get_num, set_num)}s = test() //创建对象并初始化s.name = "xiaoming"s.age = 18s.size()s.size = ("xiaofang", 8)
将size定义为一个属性的时候,调用size时,通过访问器函数的参数不同,来分别调用两个方法(不知道这样理解对不对)
至于在其他的书中,我同样看过,如果想把一个类中的方法变为属性来使用的话,使用“装饰器”@property也是可以的
=========================================================华丽的分割线=================================================================
静态成员方法和类成员方法就相当于是非绑定方法和绑定方法。类方法在定义的时候可以显示的写出cls参数(这参数是干嘛的,我也不太清楚),因为在类中如果要定义方法,无特殊情况都是类成员方法,也就是说必须有self参数,不然是不对的。也就是说,这个方法要绑定到该类的对象上面。如果一旦想要定义一个静态成员方法的话,那么要显式表明
class test(){def __init__(self):self.name=""self.age=0def get_num(self):get_num=staticmethod(get_num) #声明为静态成员方法return self.name, self.agedef set_num(self, size):self.name, self.age = sizedef print_lol(cls):print "hello world"print_lol = classmethod(print_lol) #声明为类成员方法 size = property(get_num, set_num)}
同时也可以用装饰器的办法
class test(){def __init__(self):self.name=""self.age=0@staticmethoddef get_num(self):return self.name, self.agedef set_num(self, size):self.name, self.age = size@classmethoddef print_lol(cls):print "hello world"size = property(get_num, set_num)}
看起来可能会更精简一点
我对魔法方法的一些理解:
魔法方法其实就是python中已经定义好了的一些方法。他们不会被显式的调用,一般在创建对象,或者执行一些访问特性的操作的时候,他们在类中会自动的隐式调用。比如,你设定了一个列表,那么当你用索引值引用列表中的某一个元素的时候,比如a[4],那么在list这个类里面就会自动调用__getattr__这样的魔法方法,因为这个元素被看错是一个特性,你在访问特性的同时,还要对特性进行操作。所以,魔法方法看起来很抽象,但是我们无时不刻不在使用它。
=======================================华丽的分割线===================================
迭代器:
定义:具有next()方法的对象
使用next,迭代器会返回他的下一个值,如果这个值不存在还调用了一个next,那么他会抛出一个异常
迭代器大多数用来迭代可以迭代的对象(O(∩_∩)O~,其实我也感觉这句话很绕口,反正是自己这么理解的),但是以前的迭代大多数用了列表和字典等数据结构,使用迭代器的好处就是能够尽量的缩短对空间的消耗,不会像列表一样,一次行把要迭代的元素全都放入内存,__iter__会返回一个迭代器本身,在循环中,同样可以迭代其中的所有的元素。比如,算斐波那契数列的话,如果直接用列表来迭代(假设要无限迭代),那么必然需要一个无限大的列表,如果用迭代器的话就不会。当一个类中有实现__iter__的话,那么这个类的对象就是可迭代的,如果还实现了__next__那么,这个类实例化的对象就是一个迭代器。
能使用序列的情况下,一般可以用迭代器来替换。比如现在有一个迭代器,迭代的是1--n个数字,那么就可以用list构造方法来显式的将迭代器中要迭代的元素转化为列表的形式。
=====================================华丽的分割线=====================================
生成器:
包含任何yield语句的函数都被称做是一个生成器。可以把它看做是和return 语句的性质相同,只不过它不会就此终止程序并返回一个值,而是每次执行到此处时,产生一个值,变为阻塞状态,等待下一次被激活,继续运行。
(生成器这里我暂时也没搞清楚,不过一个博客不错,推荐给大家http://blog.donews.com/limodou/archive/2006/09/04/1028747.aspx)
能吸收和理解的东西就这么多,虽然感觉都是些理论的东西,但是,还是需要了解的,这东西就好比内功,不能一味的求快,学知识还是要踏实点好。
- Python基础教程第九章--------多么痛的领悟
- 多么痛的领悟
- 多么痛的领悟。。。
- 多么痛的领悟
- 多么痛的领悟
- 多么痛的领悟!!!
- 总是想起一首歌:多么痛的领悟
- 总是想起一首歌:多么痛的领悟
- 总是想起一首歌:多么痛的领悟
- 总是想起一首歌:多么痛的领悟
- 总是想起一首歌:多么痛的领悟
- 【机房收费系统】多么痛的领悟
- webqq即将离开,多么痛的领悟
- 多么痛的领悟~ T T
- 多么好的领悟
- 多么痛的领悟-代码优化导致的BUG
- 多么痛的领悟 - SCO UNIX failover 的Change
- 我的2013拾遗总结~ 多么痛的领悟!
- Chapter 2 进程与线程 上 现代操作系统笔记
- 数据库分库分表(sharding)系列(三) 关于使用框架还是自主开发以及sharding实现层面的考量
- week_4_homework
- Java中的log4j代码
- apache+tomcat负载均衡3种实现方式
- Python基础教程第九章--------多么痛的领悟
- 设置应用内的系统控件语言
- ——————JDK开发环境部署
- 部分函数备忘
- 数据库分库分表(sharding)系列(四) 多数据源的事务处理
- AS3 Starling 塔防教程——第一部分——外部文件加载
- mongodb
- C# sqlite
- 一个二维码通吃 android , ios 下载