上一段簡短的代碼
class TestMain: def __init__(self): print('TestMain:__init__') self.a = 1 def __getattr__(self, item): print('TestMain:__getattr__') return 2 def __getattribute__(self, item): print('TestMain:__getattribute__') if item == 'c': raise AttributeError return 3 if __name__ == '__main__': t = TestMain() print(t.a) print(t.b) print(t.c)
我們知道只要定義了__getattribute__
函數,就肯定執行這個函數來獲取屬性,這次我們增加了判斷如果訪問c
這個屬性,我們拋出異常,最后的結果是:
TestMain:__init__ TestMain:__getattribute__ 3 TestMain:__getattribute__ 3 TestMain:__getattribute__ TestMain:__getattr__ 2
也就是說,如果__getattribute__
拋出了AttributeError
異常,那么會繼續訪問__getattr__
函數的。
總結: 1.如果定義了__getattribute__,那么無論訪問什么屬性,都是通過這個函數獲取,包括方法,t.f()這種也是訪問的這個函數,此時這個函數應該放回一個方法,如果像例子中,仍然返回一個數字,你會獲得一個TypeError: 'int' object is not callable錯誤 2.只要定義了__getattribute__方法,不管你訪問一個存在的還是不存在的屬性,都由這個方法返回,比如訪問t.a,雖然a存在,但是只要定義了這個訪問,那么就不是訪問最開始的a了 3.如果__getattribute__拋出了AttributeError異常,並且定了了__getattr__函數,那么會調用__getattr__這個函數,不論這個屬性到底是不是存在 4.也就是說屬性訪問的一個大致優先級是:__getattribute__ > __getattr__ > __dict__