python __getattr__ __getattribute__

setattr(x,y,z)   ----> x.y=z

setattr(Test,'x'.1)    Test 爲類對象

getattr(object,name[,default])

getattr(x,'y')   -----> x.y

不會觸發__getattribute__ 

 

__getattr__:

如果實例instance通過instance.name訪問屬性name,

如果類中沒有定義name,會觸發此方法,

類中定義了name 這個屬性,不會觸發此方法

注意:如果在__getattr__(self, attr)存在通過self.attr訪問屬性,會出現無限遞歸錯誤。

 

__getattribute__

如果實例instance通過instance.name訪問屬性name,

不管類中有沒有定義name 屬性,都會觸發此方法,

 

注意:如果在__getattribute__(self, attr)方法下存在通過self.attr訪問屬性,會出現無限遞歸錯誤

如果類中定義了__getattr__方法,除非通過__getattribute__顯式的調用它,或者__getattribute__方法出現AttributeError錯誤,否則__getattr__方法不會被調用

  • test.x =1 
  • print(test.x)      設置/訪問屬性 每次都會調用 __getattribute__方法

 

test.x =1  ---->調用__setattr__,不建議自己實現

print(test.x)  ====> 如果x屬性沒有設置__getattribute__會去調用 __getattr__方法

 

class Test1:
    def __init__(self):
        self.s = 2

    def __getattr__(self, key):
        print("__getattr___", key)
        if key == 'x':
            return 'default x'
        return key

 T = Test1()
    print(T.s) 
    #輸出 
    # 2
    print(T.f)  #類沒有f屬性,就調用了__getattr__
    #輸出
    #__getattr___ f
    #f
class Test3():
    def __init__(self):
        self.s = 2

    def __getattribute__(self, key):
        print('__getattribute__')
        if key == 'x':
            return 'default x'
        else:
            return key
----------------------
    T =Test3()  #不管類裏有沒有該屬性 都調用了__getattribute__
    print(T.s)
    #輸出:
    #__getattribute__
    #s
    print(T.x)
    # 輸出
    # __getattribute__
    # default
    # x
class Test2:
    def __init__(self):
        self.s = 2

    def __getattribute__(self, key):
        print('__getattribute__')
        if key == 'x':
            pass
            # return 'default x'
        else:
            raise AttributeError

    def __getattr__(self, key):
        print("__getattr___", key)

        return key
--------------------------------
    T = Test2()
    #輸出
    # print(T.x)
    #__getattribute__
    #None

    print(T.f) # __getattribute__ 拋出AttributeError,調用 __getattr___
    #輸出
    # __getattribute__
    # __getattr___ f
    # f

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章