關于Python特殊方法(__getattr__, __setattr__, __getattribute__)總結
- __getattr__ :獲取屬性值,經常與 __setattr__, __delattr__ 配合對屬性方法封裝管理
- 觸發條件:訪問對象的屬性,且在屬性不存在觸發(AttributeError)異常時
- 例子:
class Student(object): def __init__(self, name, alias): self.name = name self.alias = alias def __getattr__(self, item): print("獲取不存在的屬性:item:", item) return self.__dict__.get(item, None) obj = Student("binger", "binger1") print("name:", obj.name) print("age:", obj.age) # 結果-----------------> # => binger # => 獲取不存在的屬性:item: age # => None class Student2(object): def __init__(self, name, alias): self.name = name self.alias = alias obj = Student2("binger", "binger1") print("name:", obj.name) print("age:", obj.age) # 結果----------------> # name: binger # Traceback (most recent call last): # File "/Users/shujun/self/logger_app/check3.py", line 29, in <module> # print("age:", obj.age) # AttributeError: 'Student2' object has no attribute 'age'
可以實現,在獲取不存在的屬性是的,實現特定的處理
- 特點:
- 只有調用的屬性不存在
- 避免書寫過于復雜的處理,避免調用本實例的方法,以免屬性不存在,出現無限循環
- __setattr__ : 為屬性賦值
- 觸發條件:為屬性賦值
- 例子:
class Student3(object): def __init__(self, name, alias): self.name = name self.alias = alias def __setattr__(self, key, value): print("賦值:setattr: ", key, value) super().__setattr__(key, value) # 二者在一定在不存在 __getattrbute__ 時,效果是一樣的 # self.__dict__[key] = value stu = Student3(name="binger", alias="binger2") print(stu.__dict__) # 結果--------------> # 賦值:setattr: name binger # 賦值:setattr: alias binger2 # {'name': 'binger', 'alias': 'binger2'}
- 特點:
- 每次賦值,不管原屬性值是否存在
- 避免書寫過于復雜的處理,避免調用過程中,給本實例的其他屬性賦值,以免出現無限循環,可以考慮使用 self.__dict__ 或者super 形式
- self.__dict__[key] = : __dict__屬性是一個字典,所有的實例屬性都存儲在這個字典中,而修改__dict__字典中的鍵值對不會觸發__setattr__方法,如果同時定義了__getattribute__方法,那么在修改__dict__字典中的鍵值對時,由于調用了self.__dict__屬性,同樣會觸發__getattribute__方法,此時不得已使用時建議使用 supper 方式
- supper 調用父類方法實現
- __getattrbute__ : 獲取屬性值
- 觸發條件:在每次調用實例的屬性時,不管調用普通還是特殊屬性,均會觸發
- 實例:
-
class Student4(object): def __init__(self, name, alias): self.name = name self.alias = alias def __getattribute__(self, item): print("調用屬性:", item) return super().__getattribute__(item) # return self.__dict__[item] # 不能使用,否則會出現死循環 stu = Student4(name="binger", alias="binger2") print("name: ", stu.name) # 結果--------------> # 調用屬性: name # name: binger
- 特點:
- 每次調用不管屬性,均會執行,屬性不存在跑出 AttributeError 異常
- 要求使用 supper 避免死循環
- 為避免可能出現死循環,請避免和 __setattr__ 同時出現

浙公網安備 33010602011771號