目錄:
一、self是什麼
二、Python的魔法方法
三、公有和私有
四、課時37課後習題及答案
*****************
一、self是什麼
*****************
物件的方法都有一個self引數,那這個self引數是什麼呢?如果之前接觸過其它的程式語言,例如c++,那麼你應該很容易對號入座,Python的self其實就相當於C++的this指標。
如果把類比作是圖紙,那麼由類例項化後的物件才是真正可以住的房子。根據一張圖紙就可以設計出成千上萬的房子,它們長得都差不多,但它們都有不同的主人。每個人都只能回到自己的家裡,陪伴自己的孩子...所以self這裡相當於每個房子的門牌號,有了self,你就可以輕鬆找到自己的房子。Python的self是同一個道理,由同一個類可以生成無數的物件,當一個物件的方法被呼叫的時候,物件會將自身的引用作為第一個引數傳給該方法,那麼Python就知道需要操作哪個物件的方法了。
通過一個例子感受下:
class Ball: def setName(self, name): self.name = name def kick(self): print("我叫%s,該死的,誰踢我..." % self.name)
>>> a = Ball() >>> a.setName('球A') >>> # 第一個引數self告訴Python是a物件在呼叫方法,因為是隱藏的並且由Python自己傳入,所以我們這裡不需要寫進來。 >>> b = Ball() >>> b.setName('球B') >>> c = Ball() >>> c.setName('土豆') >>> a.kick() 我叫球A,該死的,誰踢我... >>> b.kick() 我叫球B,該死的,誰踢我... >>> c.kick() 我叫土豆,該死的,誰踢我...
self引數的詳解可以參考部落格:https://blog.csdn.net/CLHugh/article/details/75000104
**************************
二、Python的魔法方法
**************************
Python的物件天生擁有一些神奇的方法,它們是物件導向的Python的一切。Python的這些具有魔力的方法,總是被下劃線所包圍的,今天就來說一說一個最基本的特殊方法:_ _init_ _()。
通常把_ _init_ _()方法稱作構造方法,_ _init_ _()的魔力體現在只要例項話一個物件,這個方法就會在這個物件被建立時自動呼叫(在c++裡可以看到類似的東西,叫“建構函式”)。
其實,例項化物件時是可以傳入引數的,這些引數會自動傳入_ _init_ _()方法中,可以通過重寫這個方法來自定義物件的初始化操作。舉個例子:
class Ball: def __init__(self, name): self.name = name def kick(self): print("我叫%s,該死的,誰踢我..." % self.name)
>>> p = Ball("土豆") >>> p.kick() 我叫土豆,該死的,誰踢我...
******************
三、公有和私有
******************
一般物件導向的程式語言都會區分公有和私有的資料型別,像c++和Java它們使用public和private關鍵字,用於宣告資料是公有的還是私有的,但在Python中並沒有用類似的關鍵字來修飾。
難道Python所有東西都是透明的?也不全是,預設上物件的屬性和方法都是公開的,可以直接通過點操作符(.)進行訪問:
>>> class Person: name = '小甲魚' >>> p = Person() >>> p.name '小甲魚'
為了實現類似私有變數的特徵,Python內部採用了一種叫name mangling(名字改編)的技術,在Python中定義私有變數只需要在變數名或函式名前加上“_ _”兩個下劃線,那麼這個函式或變數就會成為私有的了:
>> class Person: __name = '小甲魚' >>> p = Person() >>> p.__name Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> p.__name AttributeError: 'Person' object has no attribute '__name'
這樣在外部將變數名“隱藏”起來了,理論上如果要訪問,就需要從內部進行:
class Person: __name = '小甲魚' def __init__(self,name): self.__name = name def getName(self): return self.__name
>>> p = Person("小甲魚") >>> p.__name Traceback (most recent call last): File "<pyshell#25>", line 1, in <module> p.__name AttributeError: 'Person' object has no attribute '__name' >>> p.getName() '小甲魚'
但是你認真琢磨一下這個技術的名字name mangling(名字改編),那麼不難發現其實Python只是動了一下手腳,把雙下橫線開頭的變數進行了改名而已。實際上在外部你使用“_類名_ _變數名”即可訪問雙下橫線開頭的私有變數了:
>>> p._Person__name '小甲魚'
(注:Python目前的私有機制其實是偽私有,Python的類是沒有許可權控制的,所有變數都是可以被外部呼叫的。)
********************************
四、課時37課後習題及答案
********************************