可以在抽象基础 class 上定义可选方法吗?

Is it OK to define optional methods on abstract base class?

在抽象基 类 上使用非抽象方法是一种好习惯吗?我的意思是,方法可以但不必出现在特定 ABC 的 sub类 上?

技术上是可行的,如下例所示(ConcreteDataProvider 不实现 disconnect;它只需要实现 connect):

from abc import ABC, abstractmethod

class AbstractDataProvider(ABC):
    @abstractmethod
    def connect(self):
        pass

    def disconnect(self):
        pass

class ConcreteDataProvider(AbstractDataProvider):
    def connect(self):
        pass


data_provider = ConcreteDataProvider()

有具体方法的ABC可以提供默认实现。标准库有几种这样的情况:

  • 使用abc.ABCMeta的例子提供了non-abstract方法

    The get_iterator() method is also part of the MyIterable abstract base class, but it does not have to be overridden in non-abstract derived classes.

  • collections.abc 模块的基础知识提供默认方法(称为“Mixin 方法”)。

    ABC Inherits from Abstract Methods Mixin Methods
    ... ... ... ...
    Iterator Iterable __next__ __iter__
    Generator Iterator send, throw close, __iter__, __next__
    ... ... ... ...

当“什么都不做”是一个合理的默认值时,具有默认实现的具体方法就没有问题 pass。当您预计许多实现都需要此方法时,这尤其有用:通过提供默认值,客户端代码始终调用此方法是安全的。


注意:当pattern具体为connect/disconnect、open/close或类似的对方法调用before/after用法时, __enter__/__exit__一对context manager是合适的接口。