为什么python允许我实例化这个类?我没有实现抽象方法

时间:2015-01-29 17:36:38

标签: python

我是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()

2 个答案:

答案 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的答案也与它有关。