類的常用魔術方法:無需人為調用,基本是在特定的時刻自動觸發,方法名被前後兩個下劃線包裹 魔術方法,總結表: __init__:構造函數。初始化的時候調用。__new__:對象實例化方法,其實這才是類裡面第一個被調用的方法,在構造函數之前調用,之後才是__init__,只是這個比較特殊,一般不使用。_ ...
類的常用魔術方法:無需人為調用,基本是在特定的時刻自動觸發,方法名被前後兩個下劃線包裹
魔術方法,總結表:
__init__:構造函數。初始化的時候調用。
__new__:對象實例化方法,其實這才是類裡面第一個被調用的方法,在構造函數之前調用,之後才是__init__,只是這個比較特殊,一般不使用。
__call__:對象當函數的時候觸發。
1 class A(): 2 def __init__(self,name = 0): 3 print("哈哈,我是構造函數") 4 5 def __call__(self): 6 print("我是__call__函數") 7 8 a = A() 9 a() #對象當函數使用,如果沒有__call__函數會報錯
__str__:當對象被當做字元串使用過的時候調用。
1 class A(): 2 def __init__(self,name = 0): 3 print("哈哈,我是構造函數") 4 5 def __str__(self): 6 return "我只是一個例子" 7 8 a = A() 9 print(a) #把對象當字元串使用
__repr__:返回字元串,跟__str__函數差不多。
屬性操作相關:
__getattr__:訪問不存在屬性的時候觸發。攔截點號運算。當對未定義的屬性名稱和實例進行點號運算時,就會用屬性名作為字元串調用這個方法。如果繼承樹可以找到該屬性,則不調用此方法
__setattr__:對成員屬性進行設置的時候觸發,有三個參數--
1,self用來獲取當前對象
2,被設置的屬性名稱,以字元串形式出現
3,需要對屬性名稱設置的值
作用:進行屬性設置的時候進行驗證或者修改。
會攔截所有屬性的的賦值語句。如果定義了這個方法,self.arrt = value 就會變成self,__setattr__("attr", value).這個需要註意。
當在__setattr__方法內對屬性進行賦值是,不可使用self.attr = value,因為他會再次調用self,__setattr__("attr", value),則會形成
無窮遞歸迴圈,最後導致堆棧溢出異常。應該通過對屬性字典做索引運算來賦值任何實例屬性,也就是使用self.__dict__['name'] = value.
1 A(): 2 def __init__(self): 3 pass 4 def __setattr__(self, name, value): 5 print("設置屬性:{0}".format(name)) 6 self.name = value #這句語句會導致死迴圈 7 8 a = A() 9 a.age = 18
所以為了避免死迴圈,規定統一調用父類魔法函數:
1 class A(): 2 def __init__(self): 3 pass 4 def __setattr__(self, name, value): 5 print("設置屬性:{0}".format(name)) 6 super().__setattr__(name,value) #super函數調用父類,避免死迴圈 7 8 a = A() 9 a.age = 18
如果在類中定義了__getitem__()方法,那麼他的實例對象(假設為P)就可以這樣P[key]取值。當實例對象做P[key]運算時,就會調用類中的__getitem__()方法。
1 # -*- coding:utf-8 -*- 2 class DataTest: 3 def __init__(self,id,address): 4 self.id=id 5 self.address=address 6 self.d={self.id:1, 7 self.address:"192.168.1.1" 8 } 9 10 def __getitem__(self,key): 11 return "hello" 12 13 14 data=DataTest(1,"192.168.2.11") 15 print data[2]
__xxxitem__: 當以[ ” “ ] 的方式訪問屬性時,就會調用此類型的方法
setitem:當屬性被以索引方式賦值的時候會調用該方法
getitem:一般如果想使用索引訪問元素時,就可以在類中定義這個方法
delitem:當使用索引刪除屬性時調用該方法
實例
1 __Author__ = "Lance#" 2 3 # -*- coding = utf-8 -*- 4 5 class Point: 6 def __init__(self): 7 pass 8 9 def __str__(self): 10 return 'Point is (%s,%s)' %(self.x, self.y) 11 12 def __setitem__(self, key, value): 13 print('Called the __setitem__ function') 14 self.__dict__[key] = value 15 16 def __getitem__(self, item): 17 print('Called the __getitem__ function') 18 try: 19 if item == 'x': 20 return '%s' %self.x 21 elif item == 'y': 22 return '%s' %self.y 23 except: 24 return 'There is no this item in class Point' 25 26 def __delitem__(self, key): 27 del self.__dict__[key] 28 29 if __name__ == '__main__': 30 p = Point() 31 p['x'] = 3 32 print(p['x']) 33 p['y'] = 6 34 print(p) 35 del p['x'] 36 print(p['x'])
運行結果
1 Called the __setitem__ function 2 Called the __getitem__ function 3 3 4 Called the __setitem__ function 5 Point is (3,6) 6 Called the __getitem__ function 7 There is no this item in class Point 8 9 Process finished with exit code 0