我的代码出错(类似于下面的错误),但结果对我来说似乎很奇怪。有人可以向我解释 getattr 是如何调用名称为"你好"?
class A(object):
def __getattr__(self, name):
print name
assert name != 'hello'
return self.hello
class C(object):
def __init__(self):
class B(A):
@property
def hello(self_):
return self.durp
self.b = B()
c = C()
print c.b.bang
这个输出是:
bang
hello
Traceback (most recent call last):
File "test.py", line 17, in <module>
print c.b.bang
File "test.py", line 5, in __getattr__
return self.hello
File "test.py", line 4, in __getattr__
assert name != 'hello'
AssertionError
shell returned 1
我当然理解C中没有durp属性(这是我所说的错误)。但是,我不希望用hello作为字符串调用__getattr__
。我觉得我不理解__getattr__
的工作原理。
答案 0 :(得分:5)
__getattr__
&#34;失败。 Python知道是否&#34;通常的方法&#34;失败的是引发了AttributeError。但是,它无法判断是否在尝试获取您尝试获取的原始属性时引发了此AttributeError,或者在该过程中访问了某些其他属性。所以发生了什么:
c.b.bang
__getattr__
被调用。__getattr__
尝试获取self.hello
hello
,其值为属性self.hello
时,Python运行hello
属性。hello
属性会尝试访问不存在的属性durp
。这引发了一个AttributeError self.hello
时引发了AttributeError,Python认为通过&#34;通常的方法&#34;没有这样的属性可用。因此,它用&#34;你好&#34;来调用__getattr__
。作为论点。这种行为令人困惑,但基本上是Python中属性查找工作方式的不可避免的副作用。知道&#34;正常属性查找没有工作的唯一方法&#34;是引发了AttributeError。关于此问题有a Python bug,显然人们仍然在努力,但到目前为止还没有真正的解决方案。
答案 1 :(得分:-1)
return self.hello
的定义中的 a.__getattr__
class A(object):
def __getattr__(self, name):
print name
assert name != 'hello'
return self.hello
触发新的属性搜索,这次使用'hello'
作为name
参数的值,这会导致您的断言失败