魚c筆記——Python魔法方法三:屬性訪問__Python

來源:互聯網
上載者:User

__getattr__(self, name)  定義當使用者試圖擷取一個不存在的屬性時的行為 : 當訪問對象的時name屬性時,若name屬性不存在,會自動調用__getattr__。如果存在,則不會調用__getattr__方法,而是直接返回name屬性

__getatribute__(self, name) 定義當該類的屬性被訪問時的行為    當訪問對象的name屬性時,無論name存不存在都會調用該方法

__setattr__(self, name, value) 定義當一個屬性被設定時的行為    當試圖給對象的name屬性進行賦值的時候調用

__delattr__(self, name) 定義當一個對象被刪除時的行為


上述四個方法中除了__getattr__以外,均可用help(object. )的方式查詢協助,但是__getattr__怎樣查詢還不太知道

只要重寫這四個魔法方法我們就可以控制對對象的屬性訪問了


這其中的三個方法和前面的getattr, setattr, delattr 是有區別的,一個由雙下劃,一個沒(愣了幾分鐘才反應過來,囧)

前面的參見:http://blog.csdn.net/sinat_41104353/article/details/79250415

>>> class C:def __getattribute__(self, name):print("getattribute")return super().__getattrbute__(name)        #為了不影響原來__getattribute__功能的使用,故調用基類的__getattribute__def __getattr__(self, name):print("getattr")                           #這裡調用super().__getattr__(name)的話會報錯:AttributeError: 'super' object has no attribute '__getattr__'def __setattr__(self, name, value):print("setattr")super().__setattr__(name, value)def __delattr__(self, name):print("delattr")super().__delattr__(name)>>> c = C()>>> c.x         #建立一個屬性xgetattribute    #首先會調用__getattribue__方法getattr>>> c.x = 1setattr>>> c.xgetattribute1               #理論上應該是1,但是不知道為什麼這裡自己試的總是getattr>>> del c.xdelattr


注意:重寫這些方法容易造成死迴圈


看下例:

寫一個矩形類,預設有長和寬兩個屬性

如果為一個叫square的屬性賦值,那麼說明這是一個正方形,值就是正方形的邊長,此時間長度和寬都應該等於邊長。如果不是為其他名字的屬性賦值,則就是為該屬性賦值。

>>> class Rectangle:def __init__(self, width = 0, height = 0):self.width = width              #發生賦值操作,就會觸發__setattr__方法self.height = heightdef __setattr__(self, name, value):if name == 'square':self.width = valueself.height = valueelse:self.name = value     #又是一個賦值操作,觸發__setatrr__方法,造成死迴圈   解決方案(1)這裡改成調用基類的__setattr__方法,即super().__setattr__(name, value),一般推薦這一種   (2)改成self.__dict__[name] = valuedef getArea(self):return self.width * self.height>>> r = Rectangle(4, 5)                        #傳入參數調用__init__方法Traceback (most recent call last):  File "<pyshell#55>", line 1, in <module>    r = Rectangle(4, 5)  File "<pyshell#54>", line 3, in __init__    self.width = width  File "<pyshell#54>", line 10, in __setattr__    self.name = value  File "<pyshell#54>", line 10, in __setattr__    self.name = value  File "<pyshell#54>", line 10, in __setattr__    self.name = value  [Previous line repeated 325 more times]  File "<pyshell#54>", line 6, in __setattr__    if name == 'square':RecursionError: maximum recursion depth exceeded in comparison

>>> r = Rectangle(4, 5)>>> r.getArea()20>>> r.square = 10>>> r.width10>>> r.height10>>> r.getArea()100

當然,不只是有__setattr__方法會造成死迴圈,__getattribute__也會,避免方法見代碼注釋。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.