1. 程式人生 > >【python】魔法之__getattribute__,__getattr__的用法總結

【python】魔法之__getattribute__,__getattr__的用法總結

1:當定義一個類的例項時,毫無疑問首先呼叫類的初始化函式 def __init__(self)。

2:當我們用的例項去訪問例項的屬性時,則首先呼叫方法  def __getatttibute__(self)

3:   在類內沒有方法 def __getattr__(self) 的前提下,如果用類的例項去呼叫一個例項不存在的屬性時,則會丟擲AttributeError異常常。

下面看程式碼:

class A(object):

    AA = 'abc'

    def __init__(self,name):

        self.myname=name

    def __getattribute__(self,x):
        print("__getattribute__() is called")
        print("x is",x)
        return object.__getattribute__(self,x)


a=A('zhangsan')
a.myname
b=a.AA
print(b)
a.zz    #類A沒有zz屬性,則會丟擲異常

輸出結果為:

__getattribute__() is called
x is myname
__getattribute__() is called
x is AA
abc
__getattribute__() is called
x is zz
Traceback (most recent call last):
  File "/home/lanliang/Projects/UNet-pytorch-master/test1.py", line 41, in <module>
    a.zz
  File "/home/lanliang/Projects/UNet-pytorch-master/test1.py", line 12, in __getattribute__
    return object.__getattribute__(self,x)
AttributeError: 'A' object has no attribute 'zz'

上面是類A沒有 __getattr__方法,下面看看有加上此方法的情況。

class A(object):

    AA = 'abc'

    def __init__(self,name):

        self.myname=name

    def __getattribute__(self,x):
        print("__getattribute__() is called")
        print("x is",x)
        return object.__getattribute__(self,x)

    def __getattr__(self, me):
        print("__getattr__() is called ",me + " from getattr")
        return None


a=A('zhangsan')
a.myname
b=a.AA
print(b,'\n')

c=a.zz
print(c)

輸出結果為:

__getattribute__() is called
x is myname
__getattribute__() is called
x is AA
abc 

__getattribute__() is called
x is zz
__getattr__() is called  zz from getattr
None

上面可以看出,當例項a呼叫類A內不存在的屬性時,也會優先先呼叫方法 __getattr__,再去呼叫__getattr__方法。

總結:

1:__getattribute__方法。即在上面程式碼中,當我呼叫例項物件a的xx屬性時,不會直接列印,而是把xx的值作為實參傳進__getattribute__方法中(引數x是我隨便定義的,可任意起名),經過一系列操作後,再把xx的值返回。Python中只要定義了繼承object的類,就預設存在屬性攔截器,只不過是攔截後沒有進行任何操作,而是直接返回.在物件屬性的呼叫中,如果沒有呼叫了不存在的屬性,則Python直譯器會報錯.

2: 要解決呼叫不存在的屬性且不報錯,則需要重寫__getattr__方法去覆蓋原方法去實現,比如返回None。