【问题标题】:PyCharm "must implement all abstract methods" on a subclass that's intentionally abstractPyCharm 在有意抽象的子类上“必须实现所有抽象方法”
【发布时间】:2019-10-06 17:57:08
【问题描述】:

我有一个抽象基类,Animal:

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def move(self):
        raise NotImplementedError()

    @abc.abstractmethod
    def eat(self):
        raise NotImplementedError()

现在我有另一个只实现以下方法之一的 abc:

class Bird(Animal):
    def move(self):
        print("fly")

另一个实现缺失方法的类:

class Eagle(Bird):
    def eat(self):
        print("eagle eats")

但是 PyCharm 抱怨 Bird 它“必须实现所有抽象方法”,而我故意希望它保持抽象。

我错过了什么,还是这是一个错误?如果它只是一个错误,我可以以某种方式忽略警告(类似于#noqa)吗?

【问题讨论】:

  • 这不是错误。抽象类的整个概念是强制子类实现所有方法。
  • @DeepSpace 那我的例子怎么样?我应该被允许拥有多个 abc 链。

标签: python-3.x pycharm abstract-class abc


【解决方案1】:

只需将Bird 也标记为抽象:

from abc import ABC

class Bird(Animal, ABC):
    def move(self):
        print("fly")

想了想,实际上,我认为为此目的指定metaclass=ABCMeta 会更有意义,就像您最初所做的那样,因为从概念上讲我们不想修改Bird 的继承层次结构,而是将其标记为抽象类(为了 PyCharm 的好处),也许这是一种更简洁的方式。

【讨论】:

  • 对,如果您考虑 imo 的继承树,这没有任何意义。此外,ABC 似乎只添加了metaclass=abc.ABCMeta,并且元类继承了所有子类,所以这在 Python 中没有做任何事情。它确实欺骗了 PyCharm,所以谢谢! :)
  • @MarkusMeskanen 关于从ABC继承;是的,这就是它所做的一切,但我个人觉得它比明确指定元类更方便。关于实际效果,你说得对,它实际上并没有做任何事情。但是,默认情况下,PyCharm 假定从抽象类继承的所有类都应该是具体的,所以这告诉 PyCharm 这个类仍然是抽象的。至于继承层次结构,因为正如您所指出的,所有这些都是更改metaclass,所以从原则的角度来看,也许使用元类方法更好;)
  • 你是对的,也许将它“重新声明”为 ABC 是件好事,这不仅是为了 PyCharm,也是为了我们的清晰。我 100% 同意在子类化 ABC 上使用 metaclass,但不幸的是它没有欺骗 PyCharm,这是我在发布问题之前尝试的第一件事。我不确定为什么子类化 ABC 有效,但重新定义元类无效,但我很高兴你想出了它。
  • 似乎已经有一个错误报告,也许它会被修复:youtrack.jetbrains.com/issue/PY-33830 现在我对你提出的解决方案很满意
  • @MarkusMeskanen 我明白了,所以这是一个错误。鉴于您已经尝试过,这听起来确实很像。实际上,我之前也偶然偶然发现了这个解决方案,因为我遇到了完全相同的问题。幸运,我猜!
猜你喜欢
  • 2016-03-08
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多