ABC班做什么?

2024-10-04 01:24:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个继承另一个类的类:

class ValueSum(SubQuery):
    output = IntegerField()

并且pycharm显示以下警告:

Class ValueSum must implement all abstract methods

然后我alt+enter向超类添加ABC。我的警告也没有了。我有几个问题:

  • 在编写子类时,我是否应该始终这样做

  • 手动实现所有方法的区别是什么 vs仅仅使用ABC

  • ABC是否向我的代码中添加了一些内容


Tags: abstract警告outputallimplementaltclasspycharm
3条回答

SubQuery是一个抽象基类(根据^{} module),其中包含一个或多个未重写的抽象方法。通过将ABC添加到基类列表中,您将ValueSum本身定义为一个抽象基类。这意味着您不必重写这些方法,但也意味着您不能实例化ValueSum本身

PyCharm提前警告您需要实现从SubQuery继承的抽象方法;如果您不这样做,那么当您实际尝试实例化ValueSum时,您将从Python中得到一个错误


至于从ABC继承做什么,答案是。。。不多这是设置元类的便利。以下是等效的:

class Foo(metaclass=abc.ABCMeta):
    ...

class Foo(abc.ABC):
    ...

元类修改__new__,以便每次尝试创建类实例时都会检查该类是否在父类中实现了所有用@abstractmethod修饰的方法

这是继面向对象编程(OOP)之后的抽象类的要点。继承自抽象类的类需要实现所有抽象方法。如果他们是抽象的,他们不需要这样做。这些抽象方法类似于接口的方法签名,内部没有任何实现。因此,如果不插入所有抽象方法,就无法创建非abtract类ABC只是一个助手类,通过从中派生来创建新的抽象类。在这里,您可以阅读有关Python中抽象类的更多信息:https://docs.python.org/3/library/abc.html

根据你的观察,你把ValueSum标记为抽象。这意味着ValueSum的所有子类都需要实现ValueSum的抽象方法及其所有抽象超类,包括SubQuery

I write class that abstracts from some class.

不是。您编写了一个类,它继承了另一个类

Should I always do this when I writing sub class?

不可以。仅当您希望类是抽象的

What is the difference between manually implementing all the methods vs just using ABC

在本例中,您将实现转发给ValueSum的所有子类。不使用ABC将迫使您在ValueSum内实现抽象方法

Does ABC add something to my code?

不。在任何情况下,不超过使用其他类/继承

“抽象基类”或abc.ABC是一个辅助类

https://docs.python.org/3/library/abc.html

以下是它们存在的原因:

The collections module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition, the collections.abc submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, if it is hashable or if it is a mapping.

这里有一个很好的例子:https://pymotw.com/2/abc/https://pymotw.com/3/abc/

来自pymotw:

忘记正确设置元类意味着具体实现没有强制实施API。为了更容易正确设置抽象类,提供了一个自动设置元类的基类

abc_abc_base.py
import abc


class PluginBase(abc.ABC):

    @abc.abstractmethod
    def load(self, input):
        """Retrieve data from the input source
        and return an object.
        """

    @abc.abstractmethod
    def save(self, output, data):
        """Save the data object to the output."""


class SubclassImplementation(PluginBase):

    def load(self, input):
        return input.read()

    def save(self, output, data):
        return output.write(data)


if __name__ == '__main__':
    print('Subclass:', issubclass(SubclassImplementation,
                                  PluginBase))
    print('Instance:', isinstance(SubclassImplementation(),
                                  PluginBase))

相关问题 更多 >