处理描述符内部引发的AttributeError的规范方法

时间:2018-06-20 14:43:58

标签: python descriptor

在定义描述符类时,您可以简单地引发AttributeError来表示该属性不可用。例如:

from typing import Any, TypeVar, MutableMapping

V = TypeVar("V")

class Desc:
    def __init__(self, key: str) -> None:
        self.key = key
    def __get__(self, instance: Any, owner: type) -> V:
        try:
            return instance._dict[self.key]
        except KeyError:
            raise AttributeError()

class C:
    foo = Desc("d")
    def __init__(self, d: MutableMapping[str, V]) -> None:
        self._dict = d

使用方式:

>>> d1 = dict(d=0, bar=0, baz=0)
>>> c = C(d1)
>>> c.foo 
0
>>> d1.update(d=1)
>>> c.foo
1
>>> hasattr(C(dict()), "foo")
False

请注意,AttributeError导致hasattr函数“静默失败”。正如descriptor protocol所描述的那样。

但是,在某些情况下,您可能希望AttributeError“冒泡”到顶部。例如:

class NewDesc:
    def __get__(self, instance, owner):
        do_complex_task(instance) # <-- AttributeError occurs here
        return instance._on_the_fly_private_attr

我发现可以通过将有问题的代码包装在try-except块中来轻松解决,该代码会引发与AttributeError不同的其他错误:

try:
    do_complex_task(instance) # <-- AttributeError occurs here
except AttributeError as e:
    raise MyError() from e

这是处理此问题的规范方法吗?这样做会让我有什么陷阱?

0 个答案:

没有答案