我是Python中的抽象类(v 2.7)的新手。我已经看了几个抽象类的教程,似乎(一种)实现抽象方法的方法是导入abc模块并使用抽象方法装饰器,就像这样。
import abc
class AbstractAlgorithm(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def load(self, input):
"""Retrieve data from the input source and return an object."""
return
@abc.abstractmethod
def save(self, output, data):
"""Save the data object to the output."""
return
class SpecificAlgorithm(object):
def load(self, input):
return input.read()
AbstractAlgorithm.register(SpecificAlgorithm)
我知道python不会让我这样做:
AbstractAlgorithm() ==> TypeError: Can't instantiate abstract class AbstractAlgorithm with abstract methods load, save
但是为什么我能够在不实现其中一个抽象方法的情况下实例化抽象类的特定版本?我认为这是不允许的。我做错了吗?
b = SpecificAlgorithm()
答案 0 :(得分:3)
SpecificAlgorithm
必须列出AbstractAlgorithm
作为其基类。否则AbstractAlgorithm
的元类中的自动检查机制不会生效。 (更确切地说,正如Martijn Pieters所指出的那样,ABCMeta
records abstract methods未在cls.__abstractmethods__
中被覆盖。实例化时,object.__new__
raises a TypeError如果找到未被覆盖的抽象方法。)
class SpecificAlgorithm(AbstractAlgorithm):
...
b = SpecificAlgorithm()
现在收益
TypeError: Can't instantiate abstract class SpecificAlgorithm with abstract methods save
答案 1 :(得分:0)
Python允许您调用父抽象方法。通过返回行,您已定义了该方法的简单实现。通过不在子类中创建实现,使用父类的实现。这是来自python docs:
注意:与Java抽象方法不同,这些抽象方法可能有一个实现。可以通过覆盖它的类的super()机制调用此实现。这可以作为使用协作多重继承的框架中超级调用的终点。
链接:https://docs.python.org/3.4/library/abc.html
编辑:我认为unutbu的答案也与它有关。