在Python中实现抽象类的最佳方法

问题描述 投票:0回答:1

在Python中实现抽象类的最佳方法是什么?

这是我所看到的主要方法:

class A(ABC):
    @abstractmethod
    def foo(self):
        pass

但是,在扩展该类时,它不会阻止调用抽象方法。

在Java中,如果尝试执行类似的操作会出错,但在Python中则不会:

class B(A):
    def foo(self):
        super().foo()
B().foo() # does not raise an error

为了复制相同的Java行为,您可以采用这种方法:

class A(ABC):
    @abstractmethod
    def foo(self):
        raise NotImplementedError

但是,实际上,即使是最正确的解决方案,我也很少见到后者。是否有特定原因偏爱第一种方法而不是第二种方法?

python-3.x oop design-patterns abstract-class pep8
1个回答
0
投票

如果您真的希望在子类之一尝试调用超类抽象方法时引发错误,那么,是的,您应该手动引发它。

现有行为实际上是很方便的:如果您的抽象方法仅包含pass,则可以在基类中插入任意数量的子类,并且只要至少一个实现抽象方法,它就可以工作。即使它们全部调用了super()等效方法,也没有检查其他任何内容。

[如果发生错误-在复杂的层次结构中将使用mixins调用NotImplementedError或其他方式,则需要在每次调用super时检查是否引发了错误,只是跳过它。 (检查super()是否会打到有条件的抽象方法可行的类,但甚至会导致模式复杂)。

由于如果您想要到达方法的层次结构的基础,就是什么都不做,那么什么也不做就很简单!

我是说,检查一下:

class A(abc.ABC):
    @abstractmethod
    def validate(self, *kwargs):
        pass

class B(A):
    def validate(self, *, first_arg_for_B, second_arg_for_B=None, **kwargs):
        super().validate(**kw,args)
        # perform validation:
        ...

class C(A)
    def validate(self, *, first_arg_for_C **kwargs):
        super().validate(**kwargs)
        # perform validation:
        ...

class Final(B, C):
    ...

B.validate和C.validate都不需要担心层次结构中的任何其他类,只需执行他们的操作并继续下去。如果A.validate会提高,则这两种方法都必须在super().validate(...)语句内或在怪异的try: ...;except ...:pass块内执行if,以获取任何好处。

© www.soinside.com 2019 - 2024. All rights reserved.