python - 类字段为

时间:2017-06-20 13:46:09

标签: python class exception inheritance

在我的代码中,我需要使一些类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中与一个类相关联,例如作为一个领域,一个特定的类型?我在互联网上找了它但没找到任何东西......

3 个答案:

答案 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)

我更进一步,让ABC例外的每一个都从X例外继承。这样,不关心它的代码就是捕获来自A.fooB.fooC.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