首页 > 解决方案 > __getattr__ 上的异常子类

问题描述

所以我(当然)正在编写一个与 API 交互的库,而 API 有时会返回错误。我想出了一个上下文管理器来捕获动态错误,但我想做一些更快的事情:

class APIError(Exception):
    def __getattr__(self, name):
        setattr(self, name, type(name, (APIError,), {}))
        return getattr(self, name)

然后我想做的是这样的:

try:
    ...
except APIError.knownerrorcode:
    ...handle...

但是,这不起作用 -__getattr__不适用于类本身。解决方法是这样做:

try:
    ...
except APIError().knownerrorcode:
    ...handle...

但这很丑陋,通常没有意义-您无法捕获异常实例,只能捕获类,但 APIError() 显然会创建一个实例。

为了解决这个问题,我APIError = APIError()在类声明之后添加,然后第二个示例运行良好。但是,在更改之后,这失败了:

try:
    ...
except APIError:
    ...handle...

因为 APIError 现在是一个实例,无法直接捕获。以下内容也无法正常工作:

class APIError(Exception):
    @classmethod
    def __getattr__(cls, name):
        setattr(cls, name, type(name, (cls,), {}))
        return getattr(cls, name)

因为装饰器将其转换为普通方法:

>>> APIError.knownerrorcode
Traceback (most recent call last):
  File "<pyshell#75>", line 1, in <module>
    APIError.knownerrorcode
AttributeError: type object 'APIError' has no attribute 'knownerrorcode'
>>> APIError.__getattr__('knownerrorcode')
<class '__main__.knownerrorcode'>

我也尝试过元类:

class meta(type):
    def __getattr__(self, name):
        setattr(self, name, type(name, (APIError,), {}))
        return getattr(self, name)

class APIError(Exception, meta):
    pass

但第二个声明导致 TypeError:

Traceback (most recent call last):
  File "<pyshell#66>", line 1, in <module>
    class APIError(Exception, meta):
TypeError: multiple bases have instance lay-out conflict

所以,我的问题是:我怎样才能__getattr__在一个类上定义一个,以便类可以被捕获为异常并且类的所有属性返回根的子类?

标签: pythoninheritancemagic-methodscustom-exceptions

解决方案


推荐阅读