物件導向進階編程

來源:互聯網
上載者:User

標籤:

1、單底線:開始的成員變數叫 保護變數(protected)  只有類對象和子類對象自己能訪問到這些變數

雙底線:開始的是 私人成員(private) 只有類對象自己能訪問,連子類對象也不能訪問

註:以單底線開頭(_foo)的代表不能直接存取的類屬性,需通過類提供的介面進行訪問,不能用“from xxx import *”而匯入;以雙底線開頭的(__foo)代表類的私人成員;以雙底線開頭和結尾的(__foo__)代表python裡特殊方法專用的標識,如 __init__()代表類的建構函式。

2、__slots__

正常情況下,定義一個class,建立一個class的執行個體後,可以給該執行個體綁定任何屬性和方法,這就是動態語言的靈活性

class Student(object):

  pass

然後,嘗試給執行個體綁定一個屬性:

s=Student()

s.name=‘zhu‘

print s.name    zhu

嘗試給執行個體綁定一個方法:

def set_age(self,age):

  self.age=age

from types import MethodType

s.set_age=MethodType(set_age,s,Student)  給執行個體綁定一個方法

s.set_age(25)

s.age  列印出25

但是給一個執行個體綁定的方法,對另一個執行個體是不起作用的,為了給所有執行個體Binder 方法,可以給類classBinder 方法:

def set_score(self,score):

  self.score=score

Student.set_score=MethodType(set_score,None,Student)  給類綁定一個方法

所以classBinder 方法後,所有執行個體都可以調用

s.set_score(100)  則s.score=100

s2=set_score(99)  則s2.score=99

 

思考:上面例子中,完全可以把set_score方法直接定義在class中,單動態綁定允許我們在程式啟動並執行過程中動態給class加上功能;這在靜態語言中很難實現

如果想要限制class的屬性,只允許Student執行個體添加name和age屬性???

為了達到限制的目的,Python允許在定義class的時候,定義一個特殊的__slots__變數,來限制class能添加的屬性

註:__slots__定義的屬性僅對當前類起作用,對繼承的子類時不起作用的;除非在子類中也定義__slots__,這樣,子類允許定義的屬性就是自身的__slots__加上父類的__slots__。

class Student(object):

  __slots__=(‘name‘,‘age‘)  用tuple定義允許綁定屬性名稱

s=Student()

s.age=25

s.name=‘zhu‘

s.score=99  報AttributeError錯誤

 

3、@property:python內建的,負責把一個方法變成屬性調用

在綁定屬性時,我們直接把屬性暴露出去,雖然寫起來簡單,但是沒有檢查參數,導致成績隨便改

s=Student()

s.score=999

這顯然不和邏輯,為了限制score的範圍,通過set_score()方法設定成績,set_score()來擷取成績,這樣在set_score()方法中就可以檢查參數了:

使用@property

@property廣泛用在類的定義中,可以讓調用者寫出減短的代碼,同時保證對參數進行必要的檢查,這樣程式在運行時就減少了出錯的可能性

 

4、多重繼承;;Mixin的目的是給一個類增加多個功能;由於Python允許使用多重繼承,因此,Mixin就是一種常見的設計

 

5、定製類:python的class中還有許多這樣有特殊用途的函數,可以協助我們定製類

  ①__str__

class Student(object):... def __init__(self, name):... self.name = name... def __str__(self):... return ‘Student object (name: %s)‘ % self.name
print Student(‘Michael‘)Student object (name: Michael)

 若沒有__str__()函數則列印結果是:<__main__.Student object at 0x109afb190>

若直接敲變數s還是>>>s=Student(‘Micheal’)

         >>>s  則<__main__.Student object at 0x109afb190>,這是因為直接顯示變數調用的不是__str__(),而是__repr__()

兩者區別:__str__() :返回使用者看到的字串

     __repr__() :返回程式開發人員看到的字串,就是為調試用的

def __str__(self):... return ‘Student object (name: %s)‘ % self.name
__repr__=__str__

這樣直接單調用執行個體s時,>>>s  則Micheal

  ②__iter__

如果一個類想被用於for ... in迴圈,類似list或tuple那樣,就必須實現一個__iter__()方法,該方法返回一個迭代對象,然後,Python的for迴圈就會不斷調用該迭代對象的next()方法拿到迴圈的下一個值,直到遇到StopIteration錯誤時退出迴圈。

以斐波那契數列為例,寫一個Fib類,可以作用於for迴圈:

class Fib(object): def __init__(self): self.a, self.b = 0, 1   # 初始化兩個計數器a,b def __iter__(self): return self   # 執行個體本身就是迭代對象,故返回自己 def next(self): self.a, self.b = self.b, self.a + self.b   # 計算下一個值 if self.a > 100000:   # 退出迴圈的條件 raise StopIteration(); return self.a   # 返回下一個值

現在,試試把Fib執行個體作用於for迴圈:

>>> for n in Fib():... print n...1123

物件導向進階編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.