天天看點

Effective Python Ver2.0_StudyNotes___getattr__、__getattribute__及__setattr__的一些知識點

__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:
"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
           
format-string-syntax

要點總結

1、如果想要用自己的方式(例如惰性地或按需地)加載并儲存對象屬性,那麼可以在該對象所屬的類裡實作

__getattr__

__setattr__

特殊方法

2、

__getattr__

隻會在屬性缺失時觸發,而

__getattribute__

則在每次通路屬性時都要觸發

3、在實作

__getattribute__

__setattr__

的過程中,如果要使用本對象的普通屬性,那麼應該通過super()(也就是object類)來使用,而不要直接使用,以避免無限遞歸

請相信自己

當我們迷茫,懶惰,退縮的時候

我們會格外的相信命運

相信一切都是命中注定

而當我們努力拼搏,積極向上時

我們會格外的相信自己

是以命運是什麼呢?

它是如果你習慣它

那它就會一直左右你

如果你想掙脫它

那它就成為你的阻礙

可如果你打破了它

那它就是你人生的墊腳石!

如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,部落客在此感謝!