python 魔法方法,屬性和迭代器

(一)魔法方法

在python中,有的名稱在前后會加上兩個下劃線,具有特殊的含義,大部分會在某些條件下自動被調(diào)用。這里簡單介紹幾種重要的魔法方法。當然這是所有用途中的一小部分。

(1)構(gòu)造方法

在類的定義中,我們常常加入構(gòu)造方法。這樣我們在創(chuàng)建該類的實例時,會自動執(zhí)行該方法:

class Bird(object):
  def __init__(self):
      self.hungry=Ture`

構(gòu)造方法繼承的注意事項

當我們創(chuàng)建一個類,并從它的超類中繼承構(gòu)造方法時,我們經(jīng)常需要重寫構(gòu)造方法。比如下面這個例子:

class SongBird(Bird):
  def __init__(self):
    self.sound='squake'`

但是我們需要注意,這樣的話這個類的實例就沒有了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ù)(會調(diào)用SongBird的所有超類的構(gòu)造函數(shù) )
def __init__(self):
super(SongBird,self).__init__()
self.sound='squake'

(2)成員訪問

我們都知道,基本的序列有a[],a[2:3]這樣的成員訪問功能,我們?nèi)绻枰覀冏约簞?chuàng)建的類也有這樣的功能,就需要類有兩種魔法方法就可以了。(如果成員可變,需要四個)
1, len(self):
2, getitem(self,key):
3, setitem(self,key,value):
4, delitem(self,key):

當然我們可以直接把類的超類設置成list,然后將我們需要修改的魔法方法重寫就可以了。

(二)屬性

有時候?qū)ο蟮奶匦灾g存在關(guān)系,比如size由width和height組成,一旦size變化,后兩者也會變化;反之同理。于是我們需要一種特殊的特性:屬性。屬性并不是在init中直接定義,而是通過訪問器(get,set等方法)定義的特性。
創(chuàng)建屬性的機制大致上有property函數(shù),__getattr__等魔法方法。

  • property函數(shù)
    property最多可以用四個參數(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):當特性name被訪問時被自動調(diào)用
__getattr__(self,name):當特性name被訪問且沒有相應對象時被自動調(diào)用
__setattr__(self,name,value):在試圖給特性name賦值時會被自動調(diào)用
__delattr__(self,name):在試圖刪除特性name時會被自動調(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)遇到了很多可以迭代的對象。序列的類就可以實現(xiàn)for a in lists這樣的操作。為了使我們自己定義的類也是可迭代對象,我們需要在類中定義__iter__的方法,它會返回一個迭代器。
迭代器是指擁有next()方法的對象,這樣我們就可以循環(huá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ù)會返回一個生成器(可以像其它迭代器一樣使用)。相對于普通函數(shù)直接生成一個列表,再對列表進行迭代的優(yōu)點是對于較大規(guī)模的數(shù)據(jù),它會逐個生成結(jié)果,節(jié)約了大量空間,如果中途需要結(jié)束的話也不用再生成后續(xù)結(jié)果。這就是迭代的優(yōu)勢。
生成器的核心是yield語句,和return語句不同的是,它不僅返回值,而且會在該處凍結(jié)函數(shù),函數(shù)重新被喚醒后從該點繼續(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容