天天看点

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类)来使用,而不要直接使用,以避免无限递归

请相信自己

当我们迷茫,懒惰,退缩的时候

我们会格外的相信命运

相信一切都是命中注定

而当我们努力拼搏,积极向上时

我们会格外的相信自己

所以命运是什么呢?

它是如果你习惯它

那它就会一直左右你

如果你想挣脱它

那它就成为你的阻碍

可如果你打破了它

那它就是你人生的垫脚石!

如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!