[Python] __getattr__() 與 __getattribute__() 的差別

[Python] __getattr__() 與 __getattribute__() 的差別

今天在處理一個 python 物件的 attribute 問題,

需要在讀取屬性 (attribute) 時作一些處理,

直覺的想法是加一個 __getattr__() 的 hook function…

不過同事提醒了一下,才發現原來還有另一個 __getattribute__()…

 

這兩個有什麼不同呢?看了一下 python 文件的說明:

  – __getattr__(): 在 attribute 不存在時才會被呼叫到。

  – __getattribute__(): 不管 attribute 存不存在,都會先被呼叫到。如果有定義此 function 的話,得手動呼叫 __getattr__() 或是 raise AttributeError,否則就算有定義 __getattr__() 也不會被呼叫到。

 

舉例來說,下面是一個 python 程式:

class A(object):
def __init__(self):
self.x = "attribute x"
a = A()
print a.x
print a.y

 

因為 a.x 存在,a.y 不存在,因此會出現 AttributeError 這個 exception:

attribute x
Traceback (most recent call last):
File "test.py", line 17, in <module>
print a.y
AttributeError: 'A' object has no attribute 'y'

 

將程式修改一下,加上 __getattr__() 的定義:

    def __getattr__(self, name):
return "value from __getattr__"

 

執行之後,a.x 的結果不變,a.y 因為 attribute 不存在,

因此取得的是 __getattr__() 回傳的值:

attribute x
value from __getattr__

 

再將程式修改一下,加上 __getattribute__() 的定義:

    def __getattribute__(self, name):
return "value from __getattribute__"

 

執行之後,雖然 a.x 屬性存在,

但 a.x 和 a.y 的結果都是從 __getattribute__() 來囉:

value from __getattribute__
value from __getattribute__

 

 

 

(本頁面已被瀏覽過 527 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料