Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么具有重定义的uu getattr_uuu()的对象会抛出TypeError?_Python_Python 2.7_Typeerror_Setattr - Fatal编程技术网

Python 为什么具有重定义的uu getattr_uuu()的对象会抛出TypeError?

Python 为什么具有重定义的uu getattr_uuu()的对象会抛出TypeError?,python,python-2.7,typeerror,setattr,Python,Python 2.7,Typeerror,Setattr,这是密码 class MyTest: def __init__(self): pass def __getattr__(self, attr): pass t = MyTest() print 'my test object: %r' %t 所以print会触发一个TypeError:“NoneType”对象不可调用,而我只想看看对象是否存在。 当然,这段代码不是很有用。但是我在一个大的代码库中有一个这样的存根类,所以我做了 if modu

这是密码

class MyTest: 
    def __init__(self):
         pass

    def __getattr__(self, attr):
        pass
t = MyTest()
print 'my test object: %r' %t
所以print会触发一个
TypeError:“NoneType”对象不可调用,而我只想看看对象是否存在。
当然,这段代码不是很有用。但是我在一个大的代码库中有一个这样的存根类,所以我做了

if module and module.class and module.class.propery:
   # do something with that property
 ...
并得到一个
类型错误:“NoneType”对象不可调用
,但该行不调用任何东西!我猜python是在幕后隐式调用某些函数

奇怪的是,如果类继承自
对象


发生了什么事?

在python 2中,使用旧式类,当您尝试在对象上调用
\uuuuurepr\uuuuuu
(打印)时,调用了
\uuuuugetattr\uuuuuu

因为您猛烈地打断了这个方法,所以它返回
None
,python试图调用
None
(因为它希望返回一个方法)

尝试调用
对象。\uuuu getattr\uuuuu
,这样做可以:

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>
报告__
我的测试对象:

这是一个特定的Python2/旧式对象问题。Python 3或新样式的对象的行为与旧样式的类不同,
\uuu getattr\uuuu
用于更广泛的属性访问,包括魔术方法。
%
运算符试图调用
t.\uuuu repr\uuuuu()
以填充
%r
占位符,但
t.\uu repr\uuuuuu
t.计算。uu getattr\uuuuuu(“\uu repr\uuuuuuu”)
,它返回
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

如果f
的情况下,
f
本身不实现
\uuuu非零\uuuuu
\uuuu len\uuuu
,其父
对象也不实现,但在这种情况下,不使用任何属性;事实上,
f
是一个对象。在
f.x
中,实例的属性dict中找到了
x
,因此直接返回其值。只有
y
,它不是由
f
Foo
object
定义的,调用
\uuuu getattr\uuuuuu
\uu getattr\uuuuuu
应该返回一些东西,而不是
None
@Jean Françoisfare<代码>无
是“某物”!您的字符串格式化操作尝试访问
t
\uuuu repr\uuuuu
属性,并且由于您使用的是旧式类(您没有从
对象
继承),
\uu getattr\uuuu
将返回
,而不是实际返回需要调用的方法。不要使用旧式类。因此'if t'也调用
\uu repr\uu()
?不,但是在布尔上下文中计算
t
会调用一些东西。使用Jean-François Fabre的建议,即在返回任何内容之前将参数打印到
\uuuu getattr\uuuuu
,应该显示
t.\uu非零
被调用以确定
t
是否真实。
>>> 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