当我说" python属性查找过程"我的意思是:当你写x.foo时,python会做什么?
在网上搜索我没有找到关于此的大量文档,我找到的最好的论文之一恢复了以下步骤的过程(你可以看到完整的文章here)
首先这看似正确,但属性查找过程有点复杂,例如对于x.foo,如果x是类或实例,它的行为不会相同。
我找到了一些无法通过这种方式解释的样本。请考虑以下python代码:
class Meta(type):
def __getattribute__(self, name):
print("Metaclass getattribute invoked:", self)
return type.__getattribute__(self, name)
def __getattr__(self, item):
print('Metaclass getattr invoked: ', item)
return None
class C(object, metaclass=Meta):
def __getattribute__(self, name):
print("Class getattribute invoked:", args)
return object.__getattribute__(self, name)
c=C()
现在使用相应的输出检查以下行:
>> C.__new__
Metaclass getattribute invoked: <class '__main__.C'>
<built-in method __new__ of type object at 0x1E1B80B0>
>> C.__getattribute__
Metaclass getattribute invoked: <class '__main__.C'>
<function __getattribute__ at 0x01457F18>
>> C.xyz
Metaclass getattribute invoked: <class '__main__.C'>
Metaclass getattr invoked: xyz
None
>> c.__new__
Class getattribute invoked: (<__main__.C object at 0x013E7550>, '__new__')
<built-in method __new__ of type object at 0x1E1B80B0>
>> c.__getattribute__
Class getattribute invoked: (<__main__.C object at 0x01438DB0>, '__getattribute__')
Metaclass getattribute invoked: <class '__main__.C'>
<bound method C.__getattribute__ of <__main__.C object at 0x01438DB0>>
>>
我的结论是(考虑到我们正在寻找x.foo):
有人可以解释一下吗?或者少告诉我在哪里可以找到关于此的文档,谢谢。
答案 0 :(得分:4)
如果您添加print("Metaclass getattribute invoked:", self, name)
,则会看到:
>>> c.__getattribute__
Class getattribute invoked: <__main__.C object at 0x2acdbb1430d0> __getattribute__
Metaclass getattribute invoked: <class '__main__.C'> __name__
<bound method C.__getattribute__ of <__main__.C object at 0x2acdbb1430d0>>
要调用元类__getattribute__
以构建表达式repr
的{{1}},以便它可以打印c.__getattribute__
的{{1}}。
btw,C
对类和元类的工作方式相同;首先在实例上查找属性,然后在实例的类型上查找。
__name__