gpt4 book ai didi

python - 为什么具有重新定义的 __getattr__() 的对象会抛出 TypeError?

转载 作者:行者123 更新时间:2023-11-28 21:33:13 25 4
gpt4 key购买 nike

这是代码

class MyTest: 
def __init__(self):
pass

def __getattr__(self, attr):
pass
t = MyTest()
print 'my test object: %r' %t

所以 print 触发了 TypeError: 'NoneType' object is not callable 而我只想查看对象是否存在。当然,此代码不是很有用。但是我在一个大代码库中有一个像这样的 stub 类,所以我做了

if module and module.class and module.class.propery:
# do something with that property
...

并得到一个 Type Error: 'NoneType' object is not callable 但是该行没有调用任何东西!我猜 python 正在幕后隐式调用一些函数。

奇怪的是,如果该类继承自Object

,则不会发生这种情况

这是怎么回事?

最佳答案

在旧式类中,__getattr__ 用于更多种类的属性访问,包括魔术方法。 % 运算符试图调用 t.__repr__() 以填充 %r 占位符,但是 t.__repr__ t.__getattr__('__repr__') 求值,返回 None

if的情况下,调用了不同的魔术方法,但出现了同样的问题。

>>> class Foo:
... def __getattr__(self, attr):
... print(attr)
...
>>> f = Foo():
>>> if f:
... pass
__nonzero__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

使用新式类,__getattr__ 仅在无法通过常规方法找到属性时调用(检查实例或任何实例的 __dict__ 属性)该类在实例的 MRO 中)。

>>> class Foo(object):
... def __init__(self):
... self.x = 3
... def __getattr__(self, attr):
... print(attr)
...
>>> f = Foo()
>>> if f:
... pass
...
>>> f.x
3
>>> f.y
y

if f 的情况下,f 本身没有实现 __nonzero____len__,也没有它的父 object,但在这种情况下,不使用任何属性;事实上,f 是一个对象。在f.x中,x是在实例的属性dict中找到的,所以直接返回它的值。只有未由 fFooobject 定义的 y 调用对 __getattr__

关于python - 为什么具有重新定义的 __getattr__() 的对象会抛出 TypeError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54949153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com