似乎Python处理AttributeError
异常非标准。
当一个类定义__getattr__
方法时,它会吞下这个异常,而不是进一步传播到堆栈顶部。最初的例外是否丢失了?
class A(object):
@property
def test(self):
raise AttributeError('message which should not be lost')
return 'this would never return'
def __getattr__(self, name):
print 'Trying get attribute: ', name
# how decide if AttributeError was already raised ??
return 42
a = A()
print a.test
# Trying get attribute: test
# 42
想象一下,AttributeError
异常可能出现在调用链中任意深度的任何地方。
问题是如何使用'message which should not be lost'
消息保留原始异常实例?是否有一些方法可以保留AttributeError而无需求助于替换为不同的异常类?
答案 0 :(得分:1)
您通过提出AttributeError
向object.__getattribute__()
handler发出该属性不存在的信号。然后定义的行为是调用__getattr__
。异常丢失,由__getattribute__
处理。来自文档:
无条件调用以实现类实例的属性访问。如果该类还定义了
__getattr__()
,则除非__getattribute__()
明确调用它或引发AttributeError
,否则不会调用后者。
如果您不希望__getattribute__
处理异常,则需要将__getattr__
行为改为自定义__getattribute__
方法:
class A(object):
@property
def test(self):
raise AttributeError('message which should not be lost')
return 'this would never return'
def __getattribute__(self, name):
try:
value = super(A, self).__getattribute__(name)
except AttributeError as ae:
# chance to handle the attribute differently
# if not, re-raise the exception
raise ae
请注意,hasattr()
function的行为方式相同;当尝试访问属性时引发异常时,它将返回False
。