__getattr__
:每當通路類對象的屬性,此時執行個體字典又找不到該屬性時,觸發__getattr__,簡言之:通路執行個體化對象沒有的屬性時觸發
__getattribute__
:主要通路對象中的屬性就會觸發此方法
__setattr__
:隻要給對象進行屬性指派操作就會觸發此方法,無論是直接指派還是通過setattr函數指派
這裡有個技巧需要知道,如果想要通路屬性或者設定屬性指派的過程不觸發方法,可以使用
__ ** __
、
super().__getattr__('name')
super().__getattribute__('name')
來處理。
super().__setattr__('key', 'value')
示例:
class DictionaryRecord:
def __init__(self, data):
self._data = data
self.a = 1
def __getattribute__(self, item):
print(f"call __getattribute__({item !r})")
data_dict = super().__getattribute__('_data') # 超類的__getattribute__方法是直接從執行個體的屬性字典擷取的,不會觸發__getattritube__
return data_dict[item]
def __setattr__(self, key, value):
print(f"__setattr__ is run...")
print(key, value)
super().__setattr__(key, value)
data = DictionaryRecord({'foo': 3})
print(data.foo)
Result:
setattr is run...
_data {'foo': 3}
a 1
call getattribute('foo')
3
Tips:format-string-syntax"Harold's a clever {0!s}" # Calls str() on the argument first "Bring out the holy {name!r}" # Calls repr() on the argument first "More {!a}" # Calls ascii() on the argument first
要點總結
1、如果想要用自己的方式(例如惰性地或按需地)加載并儲存對象屬性,那麼可以在該對象所屬的類裡實作
__getattr__
與
__setattr__
特殊方法
2、
__getattr__
隻會在屬性缺失時觸發,而
__getattribute__
則在每次通路屬性時都要觸發
3、在實作
__getattribute__
__setattr__
的過程中,如果要使用本對象的普通屬性,那麼應該通過super()(也就是object類)來使用,而不要直接使用,以避免無限遞歸
請相信自己當我們迷茫,懶惰,退縮的時候
我們會格外的相信命運
相信一切都是命中注定
而當我們努力拼搏,積極向上時
我們會格外的相信自己
是以命運是什麼呢?
它是如果你習慣它
那它就會一直左右你
如果你想掙脫它
那它就成為你的阻礙
可如果你打破了它
那它就是你人生的墊腳石!
如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,部落客在此感謝!