我编写了一个继承另一个类的类:
class ValueSum(SubQuery):
output = IntegerField()
Pycharm显示以下警告:
Class ValueSum必须实现所有抽象方法
然后我使用alt+enter
将ABC
添加到超类,那么我的警告就消失了。我有几个问题:
在编写子类时,我应该总是这样做吗?
手动实现所有方法与仅使用
ABC
之间的区别是什么?ABC
是否为我的代码添加了某些内容?
我编写了一个继承另一个类的类:
class ValueSum(SubQuery):
output = IntegerField()
Pycharm显示以下警告:
Class ValueSum必须实现所有抽象方法
然后我使用alt+enter
将ABC
添加到超类,那么我的警告就消失了。我有几个问题:
在编写子类时,我应该总是这样做吗?
手动实现所有方法与仅使用ABC
之间的区别是什么?
ABC
是否为我的代码添加了某些内容?
SubQuery
是一个抽象基类(根据abc
模块),其中有一个或多个您未覆盖的抽象方法。通过将ABC
添加到基类列表中,您定义了ValueSum
本身为抽象基类。这意味着您不必强制重写这些方法,但也意味着您不能实例化ValueSum
本身。
PyCharm提前警告您需要实现从SubQuery
继承的抽象方法;如果您不这样做,当您尝试实例化ValueSum
时,Python会报错。
ABC
的作用,答案是...并没有太多作用。这只是为了方便设置元类。以下两种方式是等效的:class Foo(metaclass=abc.ABCMeta):
...
并且
class Foo(abc.ABC):
...
__new__
方法,以便于每次尝试创建您的类的实例时都会检查该类是否已经实现了父类中用@abstractmethod
装饰的所有方法。abc.ABC
是一个辅助类。
https://docs.python.org/3/library/abc.html
这里是它们存在的一部分原因: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))
ABC
只是一个辅助类,通过从它派生新的抽象类。在这里,您可以阅读有关Python中抽象类的更多信息:https://docs.python.org/3/library/abc.html
根据您的观察,您将ValueSum
标记为抽象。这意味着,ValueSum
的所有子类都需要实现ValueSum
和所有抽象超类的抽象方法,包括SubQuery
。
我写了一个抽象类。
不是。您编写了一个继承另一个类的类。我写子类时应该总是这样做吗?
不是。只有当您想让类成为抽象类时才需要这样做。手动实现所有方法与仅使用ABC之间有什么区别?
在这种情况下,您正在将实现转发给ValueSum
的所有子类。不使用ABC
将强制您在ValueSum
内部实现抽象方法。
ABC
对我的代码有什么影响吗?
SubQuery
? - Chayim Friedman