这是代码
class MyTest:
def __init__(self):
pass
def __getattr__(self, attr):
pass
t = MyTest()
print 'my test object: %r' %t
因此,当我只想查看对象是否存在时,打印会触发TypeError: 'NoneType' object is not callable
。
授予此代码不是很有用。但是我在大型代码库中有一个像这样的存根类,所以我做了
if module and module.class and module.class.propery:
# do something with that property
...
并得到一个Type Error: 'NoneType' object is not callable
,但该行什么也没叫!我猜想python正在幕后隐式调用某些函数。
奇怪的是,如果类继承自Object
这是怎么回事?
答案 0 :(得分:3)
在旧式类中,__getattr__
用于更多种类的属性访问,包括魔术方法。 %
运算符试图调用t.__repr__()
以填充%r
占位符,但是t.__repr__
由t.__getattr__('__repr__')
求值,它返回{{1} }。
在None
情况下,调用了另一种魔术方法,但是出现了相同的问题。
if
使用新型类,仅当无法通过常规方法找到属性(检查实例或实例MRO中任何类的>>> 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__
在>>> 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
中,在实例的属性dict中找到f.x
,因此直接返回其值。只有x
(没有由y
,f
或Foo
定义的)才能调用对object
的调用。
答案 1 :(得分:2)
在python 2中,使用旧式类,当您尝试在对象上调用__repr__
(在打印时)时,就会调用__getattr__
。
由于您猛烈地使用了此方法,因此它会返回None
,而python会尝试调用None
(因为它期望返回一个方法)
尝试致电object.__getattr__
,它将起作用:
class MyTest:
def __init__(self):
pass
def __getattr__(self, attr):
print(attr) # so we see why getattr is called
return object.__getattr__(self,attr) # so it doesn't crash (neither it is useful...)
t = MyTest()
print ('my test object: %r' %t)
打印:
__repr__
my test object: <__main__.MyTest instance at 0x00000000031B3808>
这是特定的python 2 /旧式对象问题。 Python 3或新型对象的行为不同