解析Python類中的方法定義


最近在學(xué)習(xí)類過(guò)程中耕姊,綁定方法這個(gè)概念沒有理解透徹高帖,所以在網(wǎng)上找了很多相關(guān)博客找御、文章研究到底是怎么一回事。因?yàn)橛械奈恼滤愂雠c我在python3.5版本實(shí)際實(shí)驗(yàn)中有些出入乳丰,所以經(jīng)過(guò)實(shí)踐后總結(jié)出以下結(jié)論掌测。

對(duì)于Python類中,方法的定義方式产园,我們可以歸納有4種類型:

1汞斧、不帶self、cls參數(shù)且不加裝飾器(staticmethod淆两、classmethod)
2断箫、正常的方法定義拂酣,帶self參數(shù)
3秋冰、類方法:加裝飾器(classmethod)
4、靜態(tài)方法:加裝飾器(staticmethod)

下面對(duì)每一種定義的方式進(jìn)行分析:

1婶熬、不帶self剑勾、cls參數(shù)且不加裝飾器(staticmethod埃撵、classmethod)

定義代碼如下:

class Student(object):
    def func(name):
        print('my name is {}'.format(name))

我們通過(guò)用類和實(shí)例分別調(diào)用該方法:

print(Student.func)
Student.func('Tom')
print(Student().func)
Student().func('Tom')

類調(diào)用output:

<function Student.func at 0x0000000000D7D268>
my name is Tom
[Finished in 0.1s]

實(shí)例調(diào)用output:

<bound method Student.func of <__main__.Student object at 0x0000000000D444A8>>
Traceback (most recent call last):
  File "I:\MyProject\awesome-python3-webapp\www\for_test.py", line 11, in <module>
    Student().func('Tom')
TypeError: func() takes 1 positional argument but 2 were given
[Finished in 0.2s with exit code 1]

從上面的輸出我們可以看出,此種定義方法虽另,如果用類來(lái)調(diào)用該方法暂刘,那么這個(gè)方法就只是一個(gè)函數(shù),不會(huì)像綁定方法一樣會(huì)自動(dòng)傳值捂刺。傳參只需按照正常的函數(shù)傳參即可谣拣;如果用實(shí)例來(lái)調(diào)用該方法,那么這個(gè)方法就是綁定(bound)的方法族展,既然是綁定方法森缠,那么就會(huì)自動(dòng)把Student()自身作為第一個(gè)參數(shù)傳到方法中去,所以Student().func('Tom')會(huì)傳實(shí)例Student()以及'Tom'兩個(gè)參數(shù)到此方法仪缸,但是由于此方法定義時(shí)只定義了一個(gè)參數(shù)贵涵,所以就會(huì)有上述的報(bào)錯(cuò)。

2恰画、正常的方法定義宾茂,帶self參數(shù)

定義代碼如下:

class Student(object):
    def func(self, name):
        print('my name is {}'.format(name))

類調(diào)用該方法:

print(Student.func)
Student.func('Tom')

output:

<function Student.func at 0x000000000070D268>
Traceback (most recent call last):
  File "I:\MyProject\awesome-python3-webapp\www\for_test.py", line 8, in <module>
    Student.func('Tom')
TypeError: func() missing 1 required positional argument: 'name'
[Finished in 0.2s with exit code 1]

用類調(diào)用該方法,跟第一種情況一樣拴还,依然是一個(gè)函數(shù)跨晴。因?yàn)榇撕瘮?shù)有兩參數(shù)(selfname),由于實(shí)參'Tom'是傳到了形參self自沧,所以輸出中提示調(diào)用func方法少了name參數(shù)坟奥。正確的調(diào)用方式為Student.func(Student(), 'Tom')

用實(shí)例調(diào)用該方法:

print(Student().func)
Student().func('Tom')

output:

<bound method Student.func of <__main__.Student object at 0x00000000006E44A8>>
my name is Tom
[Finished in 0.2s]

可以看出實(shí)例調(diào)用該方法拇厢,得到是綁定的方法爱谁,Student()Tom參數(shù),分別傳給形參selfname孝偎。

其實(shí)第一種和第二種定義的方法是一樣的访敌,而他們的區(qū)別只是有沒有self這個(gè)參數(shù)。只要是實(shí)例調(diào)用這個(gè)方法衣盾,都是綁定的方法寺旺。都會(huì)自動(dòng)將實(shí)例自身作為第一個(gè)參數(shù)傳遞進(jìn)去。self這個(gè)參數(shù)势决,是大家約定俗成的一種參數(shù)命名阻塑,命名成a或者b都是可以的,只不過(guò)這樣命名會(huì)降低代碼的可讀性果复。下面要說(shuō)的類方法中的cls參數(shù)也是這個(gè)道理陈莽。

3、類方法:加裝飾器(classmethod)

定義代碼如下:

class Student(object):
    @classmethod
    def func(cls, name):
        print('my name is {} from {}'.format(name, cls.__name__))

用類和實(shí)例分別調(diào)用該方法:

print(Student.func)
Student.func('Tom')
print(Student().func)
Student().func('Tom')

output:

<bound method Student.func of <class '__main__.Student'>>
my name is Tom from Student
<bound method Student.func of <class '__main__.Student'>>
my name is Tom from Student
[Finished in 0.2s]

可以看出,此種定義方式走搁,用類或者實(shí)例調(diào)用独柑,都是綁定的方法。用類調(diào)用私植,會(huì)將類自身作為第一個(gè)參數(shù)傳遞到方法中忌栅。用實(shí)例調(diào)用,會(huì)將實(shí)例所屬的類作為第一個(gè)參數(shù)傳遞到方法中曲稼。

4索绪、靜態(tài)方法:加裝飾器(staticmethod)

定義代碼如下:

class Student(object):
    @staticmethod
    def func(name):
        print('my name is {}'.format(name))

用類和實(shí)例分別調(diào)用該方法:

print(Student.func)
Student.func('Tom')
print(Student().func)
Student().func('Tom')

output:

<function Student.func at 0x0000000000D6D268>
my name is Tom
<function Student.func at 0x0000000000D6D268>
my name is Tom
[Finished in 0.2s]

從上面的輸出代碼中,可以看出贫悄,使用裝飾器staticmethod裝飾的函數(shù)者春,只是一個(gè)普通函數(shù),沒有綁定方法的自動(dòng)傳值功能清女,傳參只需按照正常的函數(shù)傳參即可钱烟。

綜合上面分析,我們可以總結(jié)如下:
1嫡丙、凡是類中的方法拴袭、函數(shù),如果沒有加裝飾器曙博,當(dāng)通過(guò)類來(lái)調(diào)用的時(shí)候拥刻,得到的是普通的函數(shù),當(dāng)通過(guò)實(shí)例來(lái)調(diào)用的時(shí)候父泳,得到的是綁定方法般哼;
2、加裝飾器classmethod的方法惠窄,無(wú)論是通過(guò)類或者實(shí)例來(lái)調(diào)用蒸眠,得到的都是綁定方法,python會(huì)自動(dòng)將類本身或者實(shí)例所屬的類作為第一個(gè)參數(shù)傳遞進(jìn)去杆融;
3楞卡、加裝飾器staticmethod的方法,通過(guò)類或者實(shí)例調(diào)用脾歇,得到的都是普通函數(shù)蒋腮。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市藕各,隨后出現(xiàn)的幾起案子池摧,更是在濱河造成了極大的恐慌,老刑警劉巖激况,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件作彤,死亡現(xiàn)場(chǎng)離奇詭異踢京,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)宦棺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)黔帕,“玉大人代咸,你說(shuō)我怎么就攤上這事〕苫疲” “怎么了呐芥?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奋岁。 經(jīng)常有香客問我思瘟,道長(zhǎng),這世上最難降的妖魔是什么闻伶? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任滨攻,我火速辦了婚禮,結(jié)果婚禮上蓝翰,老公的妹妹穿的比我還像新娘光绕。我一直安慰自己,他們只是感情好畜份,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布诞帐。 她就那樣靜靜地躺著,像睡著了一般爆雹。 火紅的嫁衣襯著肌膚如雪停蕉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天钙态,我揣著相機(jī)與錄音慧起,去河邊找鬼。 笑死册倒,一個(gè)胖子當(dāng)著我的面吹牛完慧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剩失,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屈尼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拴孤?” 一聲冷哼從身側(cè)響起脾歧,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎演熟,沒想到半個(gè)月后鞭执,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體司顿,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年兄纺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了大溜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡估脆,死狀恐怖钦奋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疙赠,我是刑警寧澤付材,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站圃阳,受9級(jí)特大地震影響厌衔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捍岳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一富寿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锣夹,春花似錦作喘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至砖顷,卻和暖如春贰锁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滤蝠。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工豌熄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人物咳。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓锣险,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親览闰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芯肤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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