構(gòu)造方法——魔法方法1__init__()

構(gòu)造方法也是函數(shù)整份,但是它調(diào)用的時(shí)間是確定的,當(dāng)一個(gè)對象被創(chuàng)建之后火俄,會立即調(diào)用構(gòu)造方法讲冠。
原來我在寫objective-c和C#時(shí)都會寫構(gòu)造方法,用來初始化類中屬性谱仪。而且需要顯示的調(diào)用。
Python中有一類魔法方法(特殊方法)嗦随,初始化用到是init敬尺。

class Person:
    def __init__(self):
        self.name = "nzh"
        self.age = 25


p1 = Person()
print("p1的姓名:{0},年齡:{1}".format(p1.name, p1.age))

image.png

init函數(shù)中悬而,我們設(shè)定了兩個(gè)屬性,name和age笨奠。并且直接賦值般婆。
在調(diào)用Person()函數(shù)時(shí),它會隱式調(diào)用init()函數(shù)乡范,然后Person類的對象中的屬性就被設(shè)置了啤咽。
init()函數(shù)中默認(rèn)會傳遞一個(gè)self的參數(shù),self代表的是對象自己瓶佳,那么生成p1對象時(shí)調(diào)用的Person()函數(shù)時(shí)鳞青,這個(gè)self就代表了p1,self會對當(dāng)前對象進(jìn)行綁定厚脉。

上面的例子我們是把屬性值都定死了胶惰,這不夠靈活。如果想讓自定義屬性的值精钮,就需要給init()函數(shù)傳遞參數(shù)轨香。

# 構(gòu)造一個(gè)用戶信息
class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user1 = User("nzh", 25)
print("user1用戶的名字:{0},年齡:{1}".format(user1.name, user1.age))

Python中有一個(gè)魔法方法叫del,相當(dāng)于析構(gòu)函數(shù)科雳,它的作用是在被垃圾回收之前調(diào)用脓杉,但是發(fā)生的時(shí)間不可預(yù)知,應(yīng)該盡力避免使用尿赚。

構(gòu)造方法在繼承中的使用

現(xiàn)在有兩個(gè)類蕉堰,A和B屋讶。B是A的子類。
A中定義了一個(gè)hello方法斩芭,B中沒有定義任何內(nèi)容乐疆,當(dāng)B的對象調(diào)用hello方法時(shí),同樣可以調(diào)用迁筛。因?yàn)閔ello方法是從父類A中繼承過來的耕挨。
這里面跟構(gòu)造函數(shù)有很大關(guān)系,因?yàn)锽的構(gòu)造方法調(diào)用了A的構(gòu)造方法贪庙,如果不是這樣止邮,B中就不能調(diào)用hello方法。

那么如何調(diào)用父類的構(gòu)造方法屈扎?有兩種方式撩匕。

調(diào)用未綁定的超類構(gòu)造方法

在Python3.0之前會用到的方法,現(xiàn)在更流行用super函數(shù)模蜡,稍后說super扁凛,先說未綁定。

class Bird():
    def __init__(self):
        self.hungry = True

    def eat(self):
        if self.hungry == True:
            print("吃點(diǎn)東西...")
            self.hungry = False
        else:
            print("我不餓卤妒,謝謝")

class SongBird(Bird):
    def __init__(self):
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

s = SongBird()
s.sing()
s.eat()

image.png

這里SongBird類的對象不能調(diào)用eat方法,就是因?yàn)樵赟ongBird初始化的時(shí)候沒有調(diào)用超類的構(gòu)造方法纬朝,可以修改SongBird的初始化函數(shù)init()

class SongBird(Bird):
    def __init__(self):
        Bird.__init__(self)
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

加了一句Bird.init(self)就能調(diào)用了Bird類中的eat方法了骄呼?背后發(fā)生了一些事情蜓萄。
在調(diào)用一個(gè)實(shí)例的方法時(shí),該方法的self參數(shù)會被自動綁定到實(shí)例上(這叫綁定方法)辟犀。如果只是調(diào)用Bird.init()绸硕,而沒有給它傳遞self參數(shù),那么Bird也不知道綁定了哪個(gè)實(shí)例出嘹,而且會引發(fā)一個(gè)TypeError錯誤咬崔。

image.png

正如上圖所示,錯誤信息顯示init()方法少了一個(gè)必要的參數(shù)self只祠。
如果直接調(diào)用Bird類的Bird.init呢丸升?(看起來像是一個(gè)屬性,而非方法)
image.png

同樣可以看到墩剖,提示沒有hungry屬性岭皂,沒有提供self參數(shù)沼头,實(shí)例就不會被綁定,這樣就可以隨便提供self參數(shù)土至。
例子中是吧SongBird的self傳給了Bird的init函數(shù)(不知道這么理解對不對)陶因,這種方法就是未綁定方法(unbound)

使用super函數(shù)

首先得知道super函數(shù)只能在新式類中使用垂蜗,如果你使用過老版本的python那么就不行了。至少是2.2以后烘苹,因?yàn)閟uper是2.2新加入的特性片部。
修改SongBird類:

class SongBird(Bird):
    def __init__(self):
        super(SongBird, self).__init__()
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

為什么一個(gè)super就解決了這些問題呢档悠?其實(shí)super函數(shù)很只能,不管你的這個(gè)類繼承了多少層超類黍图,它只需要使用一次super函數(shù)就可以調(diào)用超類中的方法奴烙,前提是這些超類中都要使用super函數(shù)剖张。
super函數(shù)返回的是一個(gè)super對象搔弄,它負(fù)責(zé)對調(diào)用的方法進(jìn)行解析丰滑,以至于我們可以成功調(diào)用超類中的方法。
有多層繼承關(guān)系時(shí)炫刷,子類從下至上逐層尋找郁妈,比如D是C的子類噩咪,C是B的子類,B是A的子類涨享。
那么繼承關(guān)系就是這樣的A->B->C->D仆百。
D中先到C中找,如果C中沒有該方法栏账,再去B中找栈源,最后再去A中找甚垦。找不到會報(bào)錯涣雕,異常類型為AttributeError。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市兑障,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逞怨,老刑警劉巖叠赦,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異除秀,居然都是意外死亡糯累,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門鳞仙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寇蚊,“玉大人,你說我怎么就攤上這事棍好≌贪叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵借笙,是天一觀的道長扒怖。 經(jīng)常有香客問我,道長业稼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任低散,我火速辦了婚禮俯邓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘熔号。我一直安慰自己稽鞭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布引镊。 她就那樣靜靜地躺著朦蕴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弟头。 梳的紋絲不亂的頭發(fā)上吩抓,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音赴恨,去河邊找鬼疹娶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伦连,可吹牛的內(nèi)容都是我干的雨饺。 我是一名探鬼主播挣饥,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沛膳!你這毒婦竟也來了扔枫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤锹安,失蹤者是張志新(化名)和其女友劉穎短荐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叹哭,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍宋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了风罩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糠排。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖超升,靈堂內(nèi)的尸體忽然破棺而出入宦,到底是詐尸還是另有隱情,我是刑警寧澤室琢,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布乾闰,位于F島的核電站,受9級特大地震影響盈滴,放射性物質(zhì)發(fā)生泄漏涯肩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一巢钓、第九天 我趴在偏房一處隱蔽的房頂上張望病苗。 院中可真熱鬧,春花似錦症汹、人聲如沸硫朦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阵幸。三九已至花履,卻和暖如春芽世,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诡壁。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工济瓢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妹卿。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓旺矾,卻偏偏與公主長得像蔑鹦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子箕宙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容