《Python基础教程》读书笔记(4)之第9章魔法方法、属性和迭代器(关键词:Python/魔法方法/属性/迭代器)
2017-09-15 15:59
513 查看
第9章 魔法方法、属性和迭代器
在Python中,有点名称会在前面和后面都加上两个下划线,这种拼写表示名字有特殊含义,所以绝对不要在自己的程序中使用这种名字。由这些名字组成的集合所包含的方法称为魔法(或称特殊)方法。如果对象实现了这些方法中的某一个,那么这个方法会在特殊的情况下(确切地说是根据名字),被Python调用。而几乎没有直接调用它们的必要。9.1 准备工作
class NewStyle(object): more_code_here class OldStyle: more_code_here
NewStyle是新式的类,OldStyle是旧式的类。如果文件以
__metaclass__=type开始,那么两个类都是新式类。
注意 Python3.0中,没有“旧式”的类,也不需要显式地子类化object或者将元类设置为type。所有的类都会隐式地成为object的子类——如果没有明确超类的话,就会直接子类化;否则会简介子类化。
9.2 构造方法
在Python中创建一个构造方法很容易。只要把init方法的名字从简单的init修改为魔法版本__init__即可:
class FooBar: def __init__(self): self.somevar = 42 >>> f = FooBar() >>> f.somevar 42
注意 Python中有一个魔法方法叫做
__del__,也就是析构方法。它在对象就要被垃圾回收之前调用。但发生调用的具体时间是不可知的。所以建议尽力避免使用
__del__函数。
9.2.1 重写一般方法和特殊的构造方法
每个类都可能拥有一个或者多个超类,它们从超类那里继承行为方式。如果一个方法在B类的一个实例中被调用(或一个属性被访问),但在B类中没有找到该方法,那么就会去它的超类A里面找。class A: def hello(self): print "hello, i'm A" class B: pass
>>> a = A() >>> b = B() >>> a.hello() hello, i'm A >>> b.hello() hello, i'm A
因为B类没有定义自己的hello方法,所以,当hello被调用时,原始的信息被打印出来。
在子类中增加功能的最基本的方式是增加方法。
但是也可以重写一些超类的方法来自己定义继承的行为。
class B(A): def hello(self): print "hello, i'm B"
重写是继承机制中的一个重要内容,对于构造方法尤其重要。构造方法用来初始化新创建对象的状态,大多数子类不仅要拥有自己的初始化代码,还要拥有超类的初始化代码。问题:如果一个类的构造方法被重写,那么就需要调用超类(你说继承的类)的构造方法,否则对象可能不会被正确地初始化。
以下是一个Bird类:
__metaclass__ = type class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print 'i want to eat' self.hungry = False else: print 'no, i am full'
>>> b = Bird() >>> b.eat() i want to eat >>> b.eat() no, i am full
现在考虑子类SongBird,它添加了唱歌的行为。
class SongBird(Bird): def __init__(self): self.sound = 'yinyinyin!' def sing(self): print self.sound
>>> sb = SongBird() >>> sb.sing() yinyinyin! >>> sb.eat() Traceback (most recent call last): File "<pyshell#6>", line 1, in <module> sb.eat() File "/home/henry/dev/Python_Basic_Course/chapter9_magicMethod_attribute_iterator/classBirdDemo.py", line 7, in eat if self.hungry: AttributeError: 'SongBird' object has no attribute 'hungry'
异常清楚地说明了错误:SongBird没有hungry特性。原因是这样的:在SongBird中,构造方法被重写,但新的构造方法没有任何关于初始化hungry特性的代码。为了达到预期的效果,SongBird的构造方法必须调用其超类Bird的构造方法来确保进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数。
9.2.2 调用未绑定的超类构造方法
__metaclass__ = type class SongBird(Bird): def __init__(self): Bird.__init__(self) self.sound = 'yinyinyin!' def sing(self): print self.sound
SongBird类中只添加了一行代码——
Bird.__init__(self)。
>>> sb = SongBird() >>> sb.eat() i want to eat >>> sb.eat() no, i am full >>> sb.sing() yinyinyin!
书上的解释我没看懂,关于添加的一行代码,这里我的理解是,将超类(所继承的类)的构造方法(Bird类的
__init__方法)继承过来,暂时没时间去理解了,先这样吧。
9.2.3 使用super函数
super函数只能在新式类中使用,但不管怎样,都应该使用新式类。当前的类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。那么可以直接使用super(SongBird,self)。如下是对Bird类例子的更新:
__metaclass__ = type class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print 'i want to eat' self.hungry = False else: print 'no, i am full'
class SongBird(Bird):
def __init__(self):
super(SongBird, self).__init__()
self.sound = 'yinyinyin!'
def sing(self):
print self.sound
9.3 成员访问
本节会讨论一个有用的魔法方法集合,可以创建行为类似于序列或映射的对象。注意 协议(protocol)这个词在Python中会经常使用,它是管理某种形式的行为的规则。协议说明了应该实现何种方法和这些方法应该做什么。因为Python中的多态性是基于对象的行为的(而不是基于祖先,例如它所属的类或者超类,等等)。
9.3.1 基本的序列和映射协议
序列和映射是对象(items)的集合(collections)。为了实现它们的基本的行为(协议),如果对象是不可变的,那么就需要使用两个魔法方法,如果是可变的则需要使用4个。□
__len__(self):这个方法应该返回集合中所含项目的数量。详细见书上。
□
__getitem__(self,key):这个方法返回与所给键对应的值。详细见书上。
□
__setitem__(self,key,value):这个方法应该按一定的方式存储和key相关的value,该值随后可使用
__getitem__来获取。当然,只能为可变对象定义这个方法。详细见书上。
□
__delitem__(self,key):这个方法在对一部分对象使用del语句时被调用,同时必须删除和元素相关的键。这个方法也是为可变对象定义的。详细见书上。
!!!这本书的中文翻译相当稀烂!!!我看不下去了,换书!!!要不然就去看英文原版,妈的!!!
参考文献:
1.《Python基础教程(第2版·修订版)》。
相关文章推荐
- 《Python基础教程》 读书笔记 第九章 魔法方法、属性和迭代器(上)
- 第9章 Python笔记 魔法方法、属性和迭代器
- Python基础教程 第9章: 魔法方法、属性和迭代器 学习笔记
- python基础教程_学习笔记11:魔法方法、属性和迭代器
- 《Python基础教程》学习笔记之[D10]魔法方法、属性、迭代器之 __init__
- Python基础编程(九)魔法方法、属性和迭代器
- python基础教程_学习笔记11:魔法方法、属性和迭代器
- Python基础编程(九)魔法方法、属性和迭代器
- Python基础教程——9魔法方法、属性及迭代器【总结】
- 读书笔记--《Python基础教程第二版》--第九章 魔法方法、属性和迭代器
- Python基础教程——9魔法方法、属性及迭代器【总结】
- Python基础教程---魔法方法,属性和迭代器(1)
- python零碎知识(6)--魔法方法、属性和迭代器
- <<Python基础教程>>学习笔记 | 第09章 | 魔法方法、属性和迭代器
- Python学习之魔法方法、属性和迭代器
- 《Python基础教程》学习笔记之[D11]魔法方法、属性、迭代器
- Python入门8_方法,属性,迭代器
- python中魔法属性和魔法方法
- Python中的特殊方法、属性和迭代器
- python进阶之类常用魔法方法和魔法属性