我正在为 __getattr__
苦苦挣扎。我有一个复杂的递归代码库,让异常传播很重要。
class A(object):
@property
def a(self):
raise AttributeError('lala')
def __getattr__(self, name):
print('attr: ', name)
return 1
print(A().a)
结果是:
('attr: ', 'a')
1
为什么会有这种行为?为什么不抛出异常?此行为未记录( __getattr__
文档)。 getattr()
可以只使用 A.__dict__
。有什么想法吗?
原文由 Dave Halter 发布,翻译遵循 CC BY-SA 4.0 许可协议
在同一个类中使用
__getattr__
和属性是危险的,因为它会导致很难调试的错误。如果属性的 getter 抛出
AttributeError
,则AttributeError
被静默捕获,并调用__getattr__
通常,这会导致__getattr__
以异常失败,但如果你非常不幸,它不会,你甚至无法轻松地将问题追溯到__getattr__
。编辑:这个问题的示例代码可以在 这个答案 中找到。
除非你的财产吸气剂是微不足道的,否则你永远不能 100% 确定它不会抛出
AttributeError
。异常可能会被抛出几个层次。这是您可以执行的操作:
__getattr__
。try ... except
块到所有不平凡的属性获取器AttributeError
@property
装饰器,它捕获AttributeError
并将其重新抛出为RuntimeError
另见 http://blog.devork.be/2011/06/using-getattr-and-property_17.html
编辑:如果有人正在考虑解决方案 4(我不推荐),可以这样做:
然后在覆盖
@property
的类中使用@property_
而不是__getattr__
。