(一)魔法方法
在python中,有的名稱在前后會(huì)加上兩個(gè)下劃線刁赖,具有特殊的含義搁痛,大部分會(huì)在某些條件下自動(dòng)被調(diào)用。這里簡(jiǎn)單介紹幾種重要的魔法方法宇弛。當(dāng)然這是所有用途中的一小部分鸡典。
(1)構(gòu)造方法
在類的定義中,我們常常加入構(gòu)造方法枪芒。這樣我們?cè)趧?chuàng)建該類的實(shí)例時(shí)彻况,會(huì)自動(dòng)執(zhí)行該方法:
class Bird(object):
def __init__(self):
self.hungry=Ture`
構(gòu)造方法繼承的注意事項(xiàng)
當(dāng)我們創(chuàng)建一個(gè)類,并從它的超類中繼承構(gòu)造方法時(shí)舅踪,我們經(jīng)常需要重寫構(gòu)造方法纽甘。比如下面這個(gè)例子:
class SongBird(Bird):
def __init__(self):
self.sound='squake'`
但是我們需要注意,這樣的話這個(gè)類的實(shí)例就沒(méi)有了hungry的特性抽碌。為了讓兩種構(gòu)建方法都執(zhí)行悍赢,我們可以采取調(diào)用超類構(gòu)造方法的未綁定版本或者使用super函數(shù):
# 調(diào)用超類構(gòu)造方法的未綁定版本
def init(self):
Bird.init(self)
self.sound='squake'
#使用super函數(shù)(會(huì)調(diào)用SongBird的所有超類的構(gòu)造函數(shù) )
def __init__(self):
super(SongBird,self).__init__()
self.sound='squake'
(2)成員訪問(wèn)
我們都知道,基本的序列有a[]货徙,a[2:3]這樣的成員訪問(wèn)功能左权,我們?nèi)绻枰覀冏约簞?chuàng)建的類也有這樣的功能,就需要類有兩種魔法方法就可以了痴颊。(如果成員可變赏迟,需要四個(gè))
1, len(self):
2, getitem(self,key):
3, setitem(self,key,value):
4, delitem(self,key):
當(dāng)然我們可以直接把類的超類設(shè)置成list,然后將我們需要修改的魔法方法重寫就可以了祷舀。
(二)屬性
有時(shí)候?qū)ο蟮奶匦灾g存在關(guān)系瀑梗,比如size由width和height組成,一旦size變化裳扯,后兩者也會(huì)變化抛丽;反之同理。于是我們需要一種特殊的特性:屬性饰豺。屬性并不是在init中直接定義亿鲜,而是通過(guò)訪問(wèn)器(get,set等方法)定義的特性。
創(chuàng)建屬性的機(jī)制大致上有property函數(shù)蒿柳,__getattr__等魔法方法饶套。
- property函數(shù)
property最多可以用四個(gè)參數(shù)調(diào)用,分別是做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):當(dāng)特性name被訪問(wèn)時(shí)被自動(dòng)調(diào)用
__getattr__(self,name):當(dāng)特性name被訪問(wèn)且沒(méi)有相應(yīng)對(duì)象時(shí)被自動(dòng)調(diào)用
__setattr__(self,name,value):在試圖給特性name賦值時(shí)會(huì)被自動(dòng)調(diào)用
__delattr__(self,name):在試圖刪除特性name時(shí)會(huì)被自動(dòng)調(diào)用
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
迭代器
我們之前已經(jīng)遇到了很多可以迭代的對(duì)象妓蛮。序列的類就可以實(shí)現(xiàn)for a in lists這樣的操作。為了使我們自己定義的類也是可迭代對(duì)象圾叼,我們需要在類中定義__iter__的方法蛤克,它會(huì)返回一個(gè)迭代器。
迭代器是指擁有next()方法的對(duì)象夷蚊,這樣我們就可以循環(huán)下去了构挤。為了方便起見(jiàn),推薦我們定義的類有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
生成器
生成器函數(shù)是一種特殊的函數(shù),函數(shù)會(huì)返回一個(gè)生成器(可以像其它迭代器一樣使用)箱歧。相對(duì)于普通函數(shù)直接生成一個(gè)列表矾飞,再對(duì)列表進(jìn)行迭代的優(yōu)點(diǎn)是對(duì)于較大規(guī)模的數(shù)據(jù),它會(huì)逐個(gè)生成結(jié)果叫胁,節(jié)約了大量空間凰慈,如果中途需要結(jié)束的話也不用再生成后續(xù)結(jié)果汞幢。這就是迭代的優(yōu)勢(shì)驼鹅。
生成器的核心是yield語(yǔ)句,和return語(yǔ)句不同的是森篷,它不僅返回值输钩,而且會(huì)在該處凍結(jié)函數(shù),函數(shù)重新被喚醒后從該點(diǎn)繼續(xù)執(zhí)行仲智。
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