python類方法中的self關(guān)鍵字使用
之前學(xué)python爬蟲的時候要把函數(shù)封裝到類里面,寫成類方法,知道在python的類方法中第一個參數(shù)應(yīng)該是self,但對self代表的具體意義不甚了了。
最近在看Java,對面向?qū)ο缶幊痰牧私飧嗔艘稽c,終于徹底弄明白self到底是什么了。
Python的類
在python中,所有的類都直接或間接繼承自O(shè)bject類,定義了類之后就定義了一個命名空間,里面定義的屬性可以通過類名來引用。
新定義的類中有一些Object中有的屬性,可以在其中定義其他變量或者函數(shù)。實例化之后會創(chuàng)建一個對象,該對象脫胎于類,并且其中的屬性動態(tài)地和類中的屬性產(chǎn)生關(guān)聯(lián):
class A:
pass
a = A()
這段代碼創(chuàng)建了一個類A,并且對它進行了實例化,實例化之后的對象綁定為變量a。
我可以看看A里面和a里面分別有什么:
In [38]: dir(A) Out[38]: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
In [39]: dir(a) Out[39]: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
用dir函數(shù)輸出A中和a中的屬性后,我們可以看到A和a中的屬性是一樣的。
我們可以向其中添加屬性,添加屬性時必須初始化:
In [40]: A.b --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-40-ebcfc7dbf31a> in <module>() ----> 1 A.b AttributeError: type object 'A' has no attribute 'b'
In [41]: A.b = 1
現(xiàn)在我們可以看看A和a中的屬性發(fā)生了什么變化:
In [42]: dir(A) Out[42]: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'b']
In [43]: dir(a) Out[43]: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'b']
In [74]: A.b Out[74]: 1 In [75]: a.b Out[75]: 1
我們可以看到,在A中和它的實例化對象中現(xiàn)在都有了屬性b,而且它們的值相等。
如果我們給A的實例化對象中添加屬性呢:
In [44]: a.c = 2 In [45]: hasattr(a, c) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-45-15d927c71e90> in <module>() ----> 1 hasattr(a, c) NameError: name 'c' is not defined
竟然報錯了,c沒有定義,報錯的原因是A的實例化對象a的命名空間中有c,但是公共命名空間中沒有c,所以我們再試一次:
In [58]: c = a.c In [59]: hasattr(a, 'c') Out[59]: True In [60]: hasattr(A, 'c') Out[60]: False
我們可以看到,a中有c,但是A中并沒有c。是不是因為c指向的是a.c所以A中沒有呢:
In [61]: b = a.b In [62]: hasattr(A, 'b') Out[62]: True
確實是因為在類的實例化對象中添加的屬性不會加入類中。
我們接著看給A或a中加入函數(shù)屬性會發(fā)生什么:
In [78]: A.foo = lambda x : x + 1 In [79]: A.foo(1) Out[79]: 2 In [80]: a.foo(1) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-80-7dc85fd7a693> in <module>() ----> 1 a.foo(1) TypeError: <lambda>() takes 1 positional argument but 2 were given
python方法函數(shù)中的self關(guān)鍵字
上面執(zhí)行"a.foo(1)"語句時有個報錯,說只需要一個參數(shù),但是給了兩個參數(shù),這第二個參數(shù)是怎么來的,為什么A.foo(1)就不會出錯。
這里我們可以引出python類中的方法函數(shù),方法函數(shù)指的是通過類的實例化對象調(diào)用的函數(shù),方法函數(shù)的第一個形參表示類的實例化對象,通常寫成self。
執(zhí)行a.foo(1)時就相當(dāng)于執(zhí)行A.foo(a,1),因為A.foo()中只有一個形參,傳入的參數(shù)多于需要的參數(shù),所以發(fā)生類型錯誤。
我們在A的定義中重新定義foo:
class A:
def foo(self, n):
print(n+1)
a = A()
現(xiàn)在我們在a中調(diào)用foo就不會有問題了:
In [85]: a.foo(1) 2
我們也可以試試調(diào)用A.foo:
In [86]: A.foo(a, 1) 2
總結(jié)
python的類中定義函數(shù)時的self關(guān)鍵字跟python的方法函數(shù)有關(guān),方法函數(shù)由類的實例化對象調(diào)用,需要把調(diào)用它的實例化對象傳入方法函數(shù)中,self即是表示實例化對象的形參。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Django博客系統(tǒng)注冊之創(chuàng)建用戶模塊應(yīng)用
本文主要介紹了Django博客系統(tǒng)注冊之創(chuàng)建用戶模塊應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
python?opencv實現(xiàn)目標(biāo)外接圖形
這篇文章主要為大家詳細(xì)介紹了python?opencv實現(xiàn)目標(biāo)外接圖形,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08
python清華pip鏡像源報HTTP error 403錯誤解決辦法
這篇文章主要介紹了如何解決在使用pip安裝Python包時遇到的403錯誤,提供了三種解決方法,并強調(diào)了清除緩存以使更改生效的重要性,需要的朋友可以參考下2024-12-12
Python 實現(xiàn)「食行生鮮」簽到領(lǐng)積分功能
今天我們就用 Python 來實現(xiàn)自動簽到,省得我每天打開 APP 來操作了。感興趣的朋友跟隨小編一起看看吧2018-09-09
python和shell監(jiān)控linux服務(wù)器的詳細(xì)代碼
這篇文章主要為大家介紹了使用python和shell監(jiān)控linux服務(wù)器的詳細(xì)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06

