python中有关属性访问的下划线方法

对象本身可以定义__getattribute__()、__getattr__()、__setattr__()、__delattr__()等方法,以决定存取属性的行为:
def __getattribute__(self, name)
def __getattr__(self, name)
def __setattr__(self, name, value)
def __delattr__(self, name)

 __getattribute__()最容易理解,一旦定义了这个方法,任何属性的寻找都会被拦截,即使是那些__xxx__的內建属性名。

 __getattr__()的作用,是作为寻找属性的最后一次机会,如果同時定义有__getattribute__()、__getattr__()在尋找特性時的順序是:
1 如果有定义__getattribute__(),则返回__getattribute__()的值
2 在产生的实例的类的__dict__中寻找是否有相符的属性名。如果找到且是一个descriptor,返回__get__ ()方法的值。如果是個非descriptor ,則進行第2步
3 在实例的__dict__中寻找是否有相符的属性名,如果有則返回值
4 在产生的实例的类的__dict__中寻找是否有相符的属性名。如果不是非descriptor則直接返回属性值。如果是个只读descriptor(此時一定是仅具有__get__()方法),則返回__get__()的值
5 如果实例有定义__getattr__(),则返回__getattr__()的值
6 如果实例沒有定义__getattr__(),则丟出AttributeError

取得属性順序记忆的原则是:实例的__getattribute__()、資料描述器的__get__()、實例的__dict__、非資料描述器的__get__()、實例的__getattr__()。

__setattr__()的作用,在於攔截所有對實例的特性設定,如果對實例有個設定特性的動作,則設定的順序如下:
如果有定義__setattr__()則呼叫,如果沒有進行下一步
在產生實例的類別上,看看__dict__是否有相符合的特性名稱。如果找到 且實際是個資料描述器,則呼叫描述器的__set__()方法(如果沒有__set__()方法則丟出AttributeError),如果不是則進行下一步
在實例的__dict__上設定特性與值

設定特性順序記憶的原則是:實例的__setattr__()、資料描述器的__set__()、實例的__dict__。

__delattr__()的作用,在於攔截所有對實例的特性設定,如果對實例有個刪除特性的動作,則刪除的順序如下:
如果有定義__delattr__()則呼叫,如果沒有進行下一步
在產生實例的類別上,看看__dict__是否有相符合的特性名稱。如果找到 且實際是個資料描述器,則呼叫描述器的__delete__()方法(如果沒有__delete__()方法則丟出AttributeError),如果不是資料描述器則進行下一步
在實例的__dict__上找看看有無相符合的特性名稱,如果有則刪除,如果沒有則丟出AttributeError

刪除特性順序記憶的原則是:實例的__delattr__()、資料描述器的__delete__()、實例的__dict__。

原始来源:http://caterpillar.onlyfun.net/Gossip/Python/AttrAttribute.html