关于python:AttributeError和丢失的异常消息

AttributeError and lost exception message

似乎Python处理AttributeError异常非标准。
当类定义__getattr__方法时,它会吞下此异常,而不是进一步传播到堆栈顶部。 原来的例外是否丢失了?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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而无需求助于替换为不同的异常类的变通方法?


您通过引发AttributeErrorobject.__getattribute__()处理程序提供该属性不存在的信号。 然后定义的行为是调用__getattr__。 异常丢失,由__getattribute__处理。 从文档:

Called unconditionally to implement attribute accesses for instances of the class. If the class also defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError.

如果您不希望__getattribute__处理异常,则需要将__getattr__行为转移到自定义__getattribute__方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
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()函数的行为方式相同; 当尝试访问该属性时引发异常时,它将返回False