python - 类中派生类中预期方法的断言和文档

标签 python inheritance python-3.6 assertions docstring

假设我创建了一个名为 Bird 的类,我只想将其用作父类,并且派生类应该有一个方法 flap_wings :

class Bird:

    def fly(self):
        self.flap_wings()

预期的派生类可能如下所示:

class Eagle(Bird):

    def flap_wings(self):
        print('flapping wings')

Bird 有什么好的、清晰的方法吗?都断言其派生类具有方法 flap_wings以及包含有关 flap_wings 的文档预计会做什么?

现在,我正在使用__init_subclass__ :

class Bird:

    def fly(self):
        self.flap_wings()

    def __init_subclass__(cls, **kwargs):
        assert hasattr(cls, 'flap_wings'), (
            "Derived classes have to have a flap_wings method which should "
            "print 'flapping wings'."
        )

但是,断言表达式仅在创建 Bird 类后才会显示,并不是可以通过 help 访问的“真实”文档字符串。 .

我知道这是一个开放式问题,但是还有其他更好的方法吗?定义 flap_wings 并不违反规则Bird内首先,也许只是 body pass和文档字符串。但我只是找不到处理这种情况的“标准”方法。所以我正在寻找任何建议。

最佳答案

您可以使用 abc 库来实现抽象方法:

from abc import ABCMeta, abstractmethod
import six

class Bird(six.with_metaclass(ABCMeta)):
    def fly(self):
        """Take flight.

        Notes
        -----
        This depends on the abstract method `flap_wings`. If you've
        not implemented this at the subclass level, your subclass
        cannot be properly instantiated.
        """
        self.flap_wings()

    @abstractmethod
    def flap_wings(self):
        """Subclasses must implement this"""

这建立了某种契约(Contract)。任何未实现 flap_wings 方法的子类都会在实例化时引发错误:

class Flamingo(Bird):
    pass

>>> Flamingo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Flamingo with abstract methods flap_wings

而实现抽象方法的子类可以正常工作:

class BlueJay(Bird):
    def flap_wings(self):
        print("Flappity flap")

>>> BlueJay().fly()
Flappity flap

就记录子类而言,由于所有子类都继承 fly 方法,因此您可以在其文档字符串中包含它调用 flap_wings 方法并期望它存在.

关于python - 类中派生类中预期方法的断言和文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50974304/

相关文章:

python - 如何在Python中使用另一个变量访问命名空间变量

python - 如果一个字符串与另一个字符串共享所有字符,包括 double Python-3.x,则返回 bool

if语句中的Python数组元素

python - 如何使用 python 删除 xml 或 html 命令行并检索实际文本数据?

python - 如何使用 pythons 内置的 map 和 reduce 函数计算字符串中的字母频率

C++ 模板特化和子类化

python - mac 无法安装spark

python - pygame.quit()、quit() 或 run = False?

ruby-on-rails - 继承方法: STI? MTI?还是简单的多态关联?

objective-c - 子类可以在继承方法的参数中的 block 中添加参数吗?