当前位置: 首页 > 知识库问答 >
问题:

断言&类中派生类中所需方法的文档[重复]

年健
2023-03-14
class Bird:

    def fly(self):
        self.flap_wings()
class Eagle(Bird):

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

对于Bird来说,FLAP_WINGS既断言其派生类具有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'."
        )

但是,assert表达式只在创建Bird类之后才显示,并且不是可以通过help访问的“真正的”docstring。

我知道这是一个悬而未决的问题,但还有什么更好的方法?首先在bird中定义flap_wings并不违反规则,可能只是使用bodypass和一个docString。但我就是找不到处理这种情况的“标准”方法。所以我在寻找任何建议。

共有1个答案

钮边浩
2023-03-14

您可以将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"""

这就建立了某种契约。任何不实现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
 类似资料:
  • 如果基类A有一个“public synchronized void method(){}”没有被它的派生类B重写,那么用来访问类B中的synchronized方法的锁是什么(即是派生类对象还是基类对象)?

  • 问题内容: 我有一个类A,具有抽象方法doAction(BaseClass obj),期望类型为BaseClass的参数 现在,我还有另一个需要扩展A的类B。但是,B的doAction方法需要使用对象DerivedClass来扩展BaseClass。 当我需要将DerivedClass类型的参数传递给需要BaseClass的方法时,该如何处理呢? 谢谢! 问题答案: 您使基类通用: 以及使用派生类

  • 问题内容: 我有以下代码片段: 执行代码时出现异常: 我不明白为什么会有和例外。有人可以帮助我理解吗? 您可以在此处检查代码。 问题答案: 创建一个对象,这意味着首先调用其超类构造函数,然后依次调用-但您已覆盖它,因此它是该方法的子版本。在该方法中,您调用尚未初始化的。 结论:在构造函数中调用可重写方法几乎从来不是一个好主意。

  • 问题内容: 我有两个Java类:B,它扩展了另一个类A,如下所示: 我想打电话给。我来自C++界,我不知道如何用Java做这个基本的事情。 问题答案: 您要寻找的关键字是。例如,请参阅本指南。

  • 我可以写: 但这当然不起作用,因为调用返回的是而不是我想要的。 我可以通过在(以及和等)中键入类型并抑制警告来避免这个问题,但是即使只有(比方说)10个扩展的实体类,这仍然是为了键入而编写的样板代码。此外,我认为,如果我必须为每个派生类编写代码(无论多么小)(也会有其他类似的方法),那么拥有类层次结构的好处就会丧失很多。 对此有更好的解决方案吗? 更新:使用Java7。

  • 假设我有一个没有数据的类: 和派生类 Empty类的对象的大小为1。派生类的空部分的大小通常为0。据我所知,编译器看到基Empty类没有数据,因此它可以优化Empty的大小,以防它“在”Derived中,但标准并不要求这样做。 所以问题是: 我能在编译时确定Derived类的Empty部分并没有占用内存吗。 我知道我可以像一样进行检查...但它太冗长了,并且有几个类,如派生。有没有更优雅的解决方案