在我的代码中,我需要使一些类A,B,C继承自类X. 类A,B,C有自己的异常(A_exception,B_exception,C_exception),这些异常是从它们的方法中引出的。
class A(X):
def foo(self):
raise A_exception('A_exception')
class B(X):
def foo(self):
raise B_exception('B_exception')
class C(X):
def foo(self):
raise C_exception('C_exception')
在上面的例子中,我怎样才能避免重写foo()方法? 当然,如果foo()在类X中使用通用异常类型定义,则更好,但是从A,B,C开始,这种泛型类型应该被解析为特定类型。 是否有可能在Python中与一个类相关联,例如作为一个领域,一个特定的类型?我在互联网上找了它但没找到任何东西......
答案 0 :(得分:1)
你可以这样做:
# Modify your parent class
class X:
exception = None
def foo(self):
raise self.exception
# Define `exception` attribute in inheritor class. It should be an instance of exception
class A(X):
exception = BaseException('A_exception')
交互式控制台中的实际行为:
[2] child = A()
[3] child.foo()
---------------------------------------------------------------------------
BaseException Traceback (most recent call last)
<ipython-input-15-759019553652> in <module>()
----> 1 child.foo()
<ipython-input-9-54598e612d0a> in foo(self)
2 exception = None
3 def foo(self):
----> 4 raise self.exception
5
6
BaseException: A_exception
答案 1 :(得分:1)
尝试
Class X:
Ex= X_exception('Exception')
foo(self):
raise self.Ex
Class A(X):
Ex= A_exception('A')
答案 2 :(得分:1)
我更进一步,让A
,B
和C
例外的每一个都从X
例外继承。这样,不关心它的代码就是捕获来自A.foo
,B.foo
或C.foo
的异常,也不关心它捕获的特定异常,只要它是一个X
例外。
class XError(Exception): pass
class AError(XError): pass
class BError(XError): pass
class CError(XError): pass
class X:
exception = XError
def foo(self):
raise self.exception()
class A(X):
exception = AError
class B(X):
exception = BError
class C(X):
exception = CError
for x in [foo, bar, baz]: # List of instances of X. Could be a mix of As, Bs, and Cs
try:
x.foo()
except XError: # Will catch AError et al, but not other errors
# ...
您也可以考虑将异常类本身作为主类的属性。
class X:
class Error(Exception): pass
def foo(self):
raise self.Error()
class A(X):
class Error(X.Error): pass
class B(X):
class Error(X.Error): pass
class C(X):
class Error(X.Error): pass
try:
for x in [foo, bar, baz]:
x.foo()
except X.Error: # Will catch A.Error, B.Error, C.Error as well
# ...
这减少了一些样板,但是一些(大多数?)人可能更喜欢在模块范围声明的异常并且具有不同的名称而不是依赖于完全限定的名称。
你可能甚至可以定义一个元类,它将自动将适当的异常子类注入到类定义中;除非我今天晚些时候感到无聊,否则我会把它留作练习。
class with_exception(type):
# TODO
class X(metaclass=with_exception):
def foo(self):
raise self.Error()
class A(X):
pass
class B(X):
pass
class C(X):
pass