为什么我可以在不覆盖所有抽象方法的情况下实例化从抽象类派生的类?

时间:2016-08-19 01:12:43

标签: python-3.x abstract-class python-2.x

在互联网上的一些教程之后,我创建了这个例子:

from abc import ABCMeta, abstractmethod

class Base(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def Foo(self): 
        print('Foo base')

    @abstractmethod
    def Bar(self):
        print('Bar base')

class Sub(Base):

    def Foo(self):
        print('Foo sub')

    # no sub implementation of Bar

s = Sub() # why does this work?
s.Foo() # prints "Foo sub"
s.Bar() # prints "Bar base" (which makes sense if it's
        # **not** inheriting from an abstract class)

我的理解是,当您从包含抽象方法的类继承时,您需要覆盖所有抽象方法。为什么这样做?

1 个答案:

答案 0 :(得分:0)

tl; dr:问题是你在抽象类中使用Python 2语法,但在Python 3环境中执行。将Base类声明更改为class Base(metaclass=ABCMeta):(Python 3声明抽象类的方式)。现在,您将在实例化Base类和实例化Sub类时获得Type Error,而不会覆盖所有抽象方法。

稍微长一点的解释 - 显然这在Python 2和3之间发生了变化,然而 Python 2版本仍然是Python 3中的有效代码。在代码仍然执行的意义上它不是打破更改(它只是运行一点......不同)。您只是从基础对象类继承。您将不会收到任何警告或错误,显然Python解释器只会丢弃@abstractmethod注释。

此外,在我能够找到的任何“Python 2 vs Python 3”/“Python 2和3之间的差异”列表/文章中都没有注意到这种变化。