python類方法中的self關(guān)鍵字使用
之前學python爬蟲的時候要把函數(shù)封裝到類里面,寫成類方法,知道在python的類方法中第一個參數(shù)應該是self,但對self代表的具體意義不甚了了。
最近在看Java,對面向?qū)ο缶幊痰牧私飧嗔艘稽c,終于徹底弄明白self到底是什么了。
Python的類
在python中,所有的類都直接或間接繼承自Object類,定義了類之后就定義了一個命名空間,里面定義的屬性可以通過類名來引用。
新定義的類中有一些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)時就相當于執(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)文章
導入tensorflow時報錯:cannot import name ''abs''的解決
這篇文章主要介紹了導入tensorflow時報錯:cannot import name 'abs'的解決,文中介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10Python Numpy教程之排序,搜索和計數(shù)詳解
這篇文章主要為大家詳細介紹了Python?NumPy中排序,搜索和計數(shù)的實現(xiàn),文中的示例代碼講解詳細,對我們學習Python有一定幫助,需要的可以參考一下2022-08-08Python刪除Java源文件中全部注釋的實現(xiàn)方法
這篇文章主要介紹了Python刪除Java源文件中全部注釋的實現(xiàn)方法,涉及Python讀取文件、正則匹配、字符串查找、替換等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08