因此,(当然)我正在编写一个与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__
,以便可以将该类作为异常捕获,并且该类的所有属性 返回该子类的子类。根?