AttributeError和丢失的异常消息

时间:2015-08-24 20:43:12

标签: python

似乎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而无需求助于替换为不同的异常类?

1 个答案:

答案 0 :(得分:1)

您通过提出AttributeErrorobject.__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