(一)魔法方法
在python中,有的名称在前后会加上两个下划线,具有特殊的含义,大部分会在某些条件下自动被调用。这里简单介绍几种重要的魔法方法。当然这是所有用途中的一小部分。
(1)构造方法
在类的定义中,我们常常加入构造方法。这样我们在创建该类的实例时,会自动执行该方法:
class Bird(object):
def __init__(self):
self.hungry=Ture`
构造方法继承的注意事项
当我们创建一个类,并从它的超类中继承构造方法时,我们经常需要重写构造方法。比如下面这个例子:
class SongBird(Bird):
def __init__(self):
self.sound='squake'`
但是我们需要注意,这样的话这个类的实例就没有了hungry的特性。为了让两种构建方法都执行,我们可以采取调用超类构造方法的未绑定版本或者使用super函数:
# 调用超类构造方法的未绑定版本
def init(self):
Bird.init(self)
self.sound='squake'
#使用super函数(会调用SongBird的所有超类的构造函数 )
def __init__(self):
super(SongBird,self).__init__()
self.sound='squake'
(2)成员访问
我们都知道,基本的序列有a[],a[2:3]这样的成员访问功能,我们如果需要我们自己创建的类也有这样的功能,就需要类有两种魔法方法就可以了。(如果成员可变,需要四个)
1, len(self):
2, getitem(self,key):
3, setitem(self,key,value):
4, delitem(self,key):
当然我们可以直接把类的超类设置成list,然后将我们需要修改的魔法方法重写就可以了。
(二)属性
有时候对象的特性之间存在关系,比如size由width和height组成,一旦size变化,后两者也会变化;反之同理。于是我们需要一种特殊的特性:属性。属性并不是在init中直接定义,而是通过访问器(get,set等方法)定义的特性。
创建属性的机制大致上有property函数,__getattr__等魔法方法。
property函数
property最多可以用四个参数调用,分别是做fget,fset,fdel,doc:
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)
__getattr__,__setattr__和它的朋友们:
__getattr__(self,name):当特性name被访问时被自动调用
__getattr__(self,name):当特性name被访问且没有相应对象时被自动调用
__setattr__(self,name,value):在试图给特性name赋值时会被自动调用
__delattr__(self,name):在试图删除特性name时会被自动调用
class Rectangle:
def __init__(self):
self.width=0
self.height=0
def __setattr__(self,name,value):
if name=='size':
self.width,self.height=size
else:
self.__dict__[name]=value
def __getattr__(self,name):
if name=='size':
return self.width,self.height
else:
raise AttributeError
迭代器
我们之前已经遇到了很多可以迭代的对象。序列的类就可以实现for a in lists这样的操作。为了使我们自己定义的类也是可迭代对象,我们需要在类中定义__iter__的方法,它会返回一个迭代器。
迭代器是指拥有next()方法的对象,这样我们就可以循环下去了。为了方便起见,推荐我们定义的类有next()方法和__iter__方法,后者返回的迭代器用自己就行了。
class Fibs:
def __init__(self):
self.a=0
self.b=0
def next(self):
self.a,self.b=self.b,self.a+self.b
return self.a
def __iter__(self):
return self
for one in Fibs():
if(one>100):
print one
break
生成器
生成器函数是一种特殊的函数,函数会返回一个生成器(可以像其它迭代器一样使用)。相对于普通函数直接生成一个列表,再对列表进行迭代的优点是对于较大规模的数据,它会逐个生成结果,节约了大量空间,如果中途需要结束的话也不用再生成后续结果。这就是迭代的优势。
生成器的核心是yield语句,和return语句不同的是,它不仅返回值,而且会在该处冻结函数,函数重新被唤醒后从该点继续执行。
def flatten(nexted):
for sublist in nested:
for element in sublist:
yield element
nested=[[1,2],[2,6],[5]]
for num in flatten(nested):
print num