只想回答一个问题: 当编译器要读取obj.field
时, 发生了什么?
看似简单的属性访问, 其过程还蛮曲折的. 总共有以下几个step:
1. 如果obj
本身(一个instance )有这个属性, 返回. 如果没有, 执行 step 2
2. 如果obj
的class 有这个属性, 返回. 如果没有, 执行step 3.
3. 如果在obj
class 的父类有这个属性, 返回. 如果没有, 继续执行3, 直到访问完所有的父类. 如果还是没有, 执行step 4.
4. 执行obj.__getattr__
方法.
通过以下代码可以验证:
class A(object):
a = 'a'
class B(A):
b = 'b'
class C(B):
class_field = 'class field'
def __getattr__(self, f):
print('Method {}.__getattr__ has been called.'.format(
self.__class__.__name__))
return f
c = C()
print c.a
print c.b
print c.class_field
print c.c
输出:
a
b
class field
Method C.__getattr__ has been called.
c
PS: python里的attribute与property不同, 当使用了property里, property的解析优先级最高. 详见blog:从attribute到property.