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

2024-04-23 18:59:30 发布

您现在位置:Python中文网/ 问答频道 /正文

定义描述符类时,只需发出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

这是处理这个问题的标准方法吗?我这样做会让自己陷入什么陷阱


Tags: instancekeyfromselffoodefanydict