課時37:類與物件:物件導向程式設計

那是個好男孩發表於2018-08-23

目錄:

  一、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課後習題及答案

********************************

 

相關文章