我和__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__ documentation)。getattr()可以直接使用A.__dict__。有什么想法吗?
发布于 2014-06-17 18:03:51
在同一个类中使用__getattr__和属性是危险的,因为它可能导致很难调试的错误。
如果一个属性的getter抛出AttributeError,那么这个AttributeError就会被静默捕获,然后__getattr__就会被调用。通常,这会导致__getattr__失败并引发异常,但如果您非常不幸,它就不会失败,而且您甚至不能轻松地将问题追溯到__getattr__。
除非你的属性getter是微不足道的,否则你永远不能100%确定它不会抛出AttributeError。异常可能会抛出多个级别。
下面是你可以做的:
try ... except块@property装饰器,该装饰器会捕获<代码>D19__getattr__ >并将其作为代码重新抛出另请参阅http://blog.devork.be/2011/06/using-getattr-and-property_17.html
编辑:如果有人正在考虑解决方案4(我不推荐),可以这样做:
def property_(f):
def getter(*args, **kwargs):
try:
return f(*args, **kwargs)
except AttributeError as e:
raise RuntimeError, "Wrapped AttributeError: " + str(e), sys.exc_info()[2]
return property(getter)然后在覆盖__getattr__的类中使用@property_而不是@property。
https://stackoverflow.com/questions/11116896
复制相似问题