1 自定义属性的访问 - Customizing attribute access
2
3 在 python 中, 下列方法可以实现类实例属性 instance.attribute 的 使用,设置,删除.
4 object.__getattr__(self, name)
5 找不到 attribute 的时候被调用(__dict__ 属性中找不到的时候),
6 例如, 所调用的 attribute 不是 instance.attribute, 或者类中没有这个 attribute,
7 即 self.attribute 找不到. 该方法返回的是的 attribute 的 value, 或者
8 raise AttributeError 异常.
9
10 Note,
11 如果 attribute 存在 __dict__ 中, __getattr__ 是不会被调用的.
12 这一点体现了 __getattr__ 与 __setattr__ 的非对称调用, 这种不
13 对称是 python 故意儿为之, 原因有二,
14 a, 为了效率的原因 - 找到 attribute 后,无需浪费资源再'向上(MRO)'查找.
15 b, 如果不这样做 __getattr__ 将无法访问 instance 的其他 attributes.
16 至少对于 instance variables 来说, 可以通过在 __dict__ 中插入变量的值来实现,
17 __dict__[variables] = value,从而得到对该 variables 的访问及控制(total control).
18 上面这样这种做法, 在 python doc 中被称为 'fake total control', 相对应的后面将
19 介绍的 __getattribute__ 方法被称作'actually get total control'.
20
21 object.__getattribute__(self, name)
22 在获取 instances.attribute 的时候无条件的被调用.
23 如果在 instances 所属的 class 中定义了 __getattr__ 方法, __getattr__ 将不会被调用,
24 除非在 __getattribute__ 方法中显示的调用 __getattr__, 或者 __getattribute__ 方法
25 raises AttributeError 异常.
26 为防止无线的递归, 调用 __getattribute__ 方法的时候应该保证始终在 instances 的基类上调用.
27 Note,
28 有种情况可能绕过此方法,即 通过 隐式调用 或 built-in 方法调用'特殊方法'的时候,
29 详见 '对特殊方法的访问 - Special method lookup' 一文.
http://www.cnblogs.com/zzyzz/p/7743687.html
30
31 object.__setattr__(self, name, value)
32 当试图设置 attributes 的时候 __setattr__ 将被调用(instances.attribute = value),
33 从而代替 normal mechanism - __dict__[variables] = value
34 当 __setattr__ 要为一个 instance 的名字为 name 的 attribute 设置成值为 value 的时候,
35 实际上应该保证调用的是基类的 __setattr__ 方法, object.__setattr__(self, name, value).
36
37 object.__delattr__(self, name)
38 跟 __setattr__ 像类似, __delattr__ 用在删除 instances.attribute 的时候.
39 del instances.attribute
40
41 object.__dir__(self)
42 当对一个对象调用 dir(object) 方法的时候 __dir__ 被调用.
43 返回值是一个被 list 化, 并 sort 的序列.
44
45 Summarize,
46 其实 Customizing attribute access 跟 descriptor 关系紧密, 是描述符协议的前提,
47 可以将两者放在一起学习.
48
49 Reference,
50 Customizing attribute access
51 https://docs.python.org/3/reference/datamodel.html#customizing-attribute-access
52
53 descriptors
54 https://docs.python.org/3/reference/datamodel.html#descriptors