9.2构造方法
构造方法和普通方法的不同之处在于,当一个对象被创建后,会立即调用构造方法。
class FooBar:
def __init__(self):
self.somevar=42
f=FooBar()
>>>f.somevar
42
9.2.3super函数
当子类重写了父类的某一方法后,如果想调用父类的这一方法,可以使用super函数。
class Bird:
def __init__(self):
self.hungry=True
def eat(self):
ifself.hungry:
print('Aaaah')
classSongBird(Bird):
def __init__(self):
super(SongBird,self).__init__()
self.sound='squawk'
def sing(self):
print(self.sound)
>>>sb=SongBird()
>>>sb.sing()
squawk
>>>sb.eat()
Aaaah
上例中,首先在重写的构造方法中调用了父类的构造方法,使子类获得hungry属性,然后又加入了自己的sound属性。
9.3成员访问
9.3.1基本的序列和映射规则
序列和映射是对象的集合。为了实现他们基本的行为,如果对象时不可变的,就需要使用两个魔法方法,如果是可变的则需要使用4个。
__len__(self): 返回集合中所有项目的数量。如果是映射,则返回键值对的数量。如果返回0,则会被当作一个布尔变量
__getitem__(self,key)返回与对应的键对应的值,对于一个长度n的序列,键是一个0-n-1的整数
__setitem__(self,key,value):根据一定的方式存储和key对应的value,只能用于可修改对象。
__delitem__(self,key):这个方法对一部分对象使用del语句时被调用
对于一个序列来说,负整数从末尾开始计数,换句话说 x[-n]和x[len(x)-n]是一样的。
9.3.1子类化列表,字典和字符串。
下面例子,带有访问计数的列表
class CounterList(list):
def __init__(self,*args):
super(CounterList,self).__init__(*args)
self.counter=0
def __getitem__(self,index):
self.counter+=1
returnsuper(CounterList,self).__getitem__(index)
在CounterList类中,重写了父类的__init__ 和__getitem__方法, 在构造方法中初始了counter属性,每次列表元素被访问时这个值加一。
cl=CounterList(range(10))
>>> cl
[0, 1, 2, 3, 4, 5,6, 7, 8, 9]
>>>cl[2]+cl[4]
6
>>>cl.counter
2
9.4更多魔力
略
9.5属性
9.5.1property函数
class Rectangle:
def __init__(self):
self.width=0
self.height=0
def setSize(self,size):
self.width,self.height=size
def getSize(self):
return self.width,self.height
size=property(getSize,setSize)
r=Rectangle()
>>> r.width=10
>>> r.height=5
>>> r.size
(10, 5)
9.6迭代器
9.6.1迭代器规则
__iter__方法返回一个迭代器,所谓我的迭代器就是具有next方法的对象。在调用next方法时,迭代器会返回它的下一个值。
使用迭代器实现斐波那契数列:
class Fibs:
def__init__(self):
self.a=0
self.b=1
def__next__(self):
self.a,self.b=self.b,self.a+self.b
return self.a
def__iter__(self):
return self
在遍历过程中使用迭代器,自动算出下一个值
>>> fibs=Fibs()
>>> for f in fibs:
iff>1000:
print(f)
break
1597
9.7生成器
生成器是一种用普通函数语法定义迭代器。
9.7.1创建生成器
参数是一个列表 如下形式:
>>> nested=[[1,2],[3,4],[5]]
函数应该按顺序打印出列表中的数字:
def flatten(nested):
for sublistin nested:
forelement in sublist:
yieldelement
任何包含yield语句的函数称为生成器。每次产生一个值(使用yield语句),函数就会被冻结:即函数停在那点等待被激活。函数被激活后就从停止的那点开始被激活:
下面通过在生成器上迭代来使用上面的值
f
or num in flatten(nested):
print(num)
1
2
3
4
5
9.7.2递归生成器
当不知道需要使用几层嵌套的时候,应该使用更灵活的,递归的方法:
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
exceptTypeError:
yield nested
当flatten被调用时,有两种可能:基本情况和需要递归的情况。 在基本情况,函数会被告知展开一个元素(比如一个数字),这种情况下,会引发一个TypeError异常(因为试图对一个数字进行迭代),生成器会产生一个元素。
如果展开一个列表(或者其他的可迭代对象),那么就要进行特殊处理。
9.7.3通用生成器
生成器由两部分组成:生成器的函数和生成器的迭代器