分类目录:《系统学习Python》总目录
文章《系统学习Python——装饰器:“私有“和“公有“属性案例-[实现私有属性]》中的代码中__setattr__方法依赖于一个实例对象的__dict__属性命名空间字典,以设置onlnstance自己的wrapped属性。正如我们在之前的文章中所了解到的,这一方法不能在没有循环的情况下直接赋值一个属性。然而,它使用了__setattr__内置函数而不是__dict__字典来设置被包装对象自身之中的属性。此外,__getattr__用来获取被包装对象中的属性,因为它们可能存储在对象自身中或者由对象继承。
因此,这段代码将对大多数类有效,包括那些带有基于slot、property、描述符的“虚拟"类级别属性,甚至还包括__setattr__及其同类。通过只为它自己设定一个命名空间字典,并且为被包装的对象使用存储中立的工具,包装器类就可以避免其他工具中的内在局限。
例如,我们可能还知道带有__slots__的新式类也许不能把属性存储到一个__dict__中(并且实际上甚至不能在其中存储任何属性)。然而,由于我们在这里只是在onlnstance层级依赖于一个__dict__字典,而不是在被包装的实例中,因此这一担忧并不适用。除此以外,因为setattr和getattr应用于基于__dict__和__slots__的属性,所以我们的装饰器应用于使用任何一种存储方案的类。基于同样的原因,装饰器也适用于新式property和相似的工具:在被包装实例中委托的名称会被重新查找,而与装饰器代理对象自己的属性无关。
参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.