在python語言中編寫面向?qū)ο蟮拇a時,都會遇到 self 這個參數(shù),其代表一個類的實例。使用 self 訪問一個類的方法和屬性,就綁定了用參數(shù)所要表示的屬性,之所以這樣做的原因是,python沒有提供相應(yīng)的語法來指向?qū)嵗膶傩?。python 中調(diào)用類的方法都是類的實例自動傳遞自身所擁有的方法,而不是自動接收傳遞來的方法:方法的第一個參數(shù)就是方法要調(diào)用的實例,self 總是指向當(dāng)前對象。
看看下面一段代碼中,self 和 obj 是否指向同一個對象:
class check: def __init__(self): print(' self 在內(nèi)存中的地址:',id(self)) obj = check()print(' 類的對象在內(nèi)存的地址:',id(obj))
輸出結(jié)果:
self 在內(nèi)存中的地址: 2074376855360
類的對象在內(nèi)存的地址: 2074376855360
接下來再看一段使用 self 的示例代碼:
class car(): # init 方法, 即constructor def __init__(self, model, color): self.model = model self.color = color def show(self): print('車型:', self.model ) print('顏色:', self.color ) # 兩個對象有不同的 self,各自的self包含各自的屬性audi = car('奧迪 a4', '藍(lán)色')ferrari = car('法拉利 488', '紅色') audi.show() #car.show(audi) # 輸出結(jié)果與上句相同ferrari.show() #car.show(ferrari) # 輸出結(jié)果與上句相同 # 也可以像以下這樣使用print('奧迪車型是: ',audi.model)print('法拉利的顏色是: ',ferrari.color)
輸出結(jié)果如下圖:
在以上這段代碼中,這兩句print('奧迪車型是: ',audi.model) 和 print('法拉利的顏色是: ',ferrari.color) ,首先由constructor構(gòu)建方法,給兩個具體的對象指定了具體的對象,再給屬性賦值,就完成了對象的初始化,屬性(model,color)和對象(audi,ferrari)就建立了聯(lián)系。這種情形的背后,每個實例中都調(diào)用了方法,并把實例及其對應(yīng)的方法一起發(fā)送給所調(diào)用的方法(car.show(audi),car.show(ferrari)),其中 self 是constructor構(gòu)建方法和實例方法要傳遞的第一個參數(shù)。
對于實例的方法和 constructor 構(gòu)建方法而言,self 必須作為第一個參數(shù),否則就會報錯。看看下面的示例代碼:
# Self 必須是第一個參數(shù)class check: def __init__(): print('這是構(gòu)建方法 Constructor') object = check()print(' 本段代碼運行正常') # 沒有把 self 作為參數(shù)傳遞,所以報錯以下錯誤Traceback (most recent call last): File '/home/c736b5fad311dd1eb3cd2e280260e7dd.py', line 6, in <module> object = check()TypeError: __init__() takes 0 positional arguments but 1 was given
以上代碼段中,類check中定義的 __init__ 方法沒有把 Self 作為參數(shù)傳遞,運行即報錯,如下圖所示:
特別注意:Self 是python中的一種慣例用法,可以稱為(實例方法的)參數(shù),但不是關(guān)鍵字,可以用其他的名稱代替,但一般建議還是使用 Self 這個名稱,以便更容易地閱讀代碼。
以下代碼段中 把 Self 替換為其他名稱:
class this_is_class: def __init__(in_place_of_self): print('把參數(shù) Self的名稱改為 in_place_of_self') object = this_is_class()
輸出結(jié)果如下圖:
(本文完)