能够实例化python类,尽管它是抽象的(使用abc)

Able to instantiate python class, in spite of it being Abstract (using abc)

这是关于这个问题的答案"使用python的abc模块来创建抽象类"(作者@alexasvassel,接受为答案)。

我试过这些建议,但奇怪的是,尽管按照建议使用abc的方式,它对我不起作用。因此,我把它作为一个问题贴在这里:

下面是我的python代码:

1
2
3
4
5
6
7
8
9
10
11
from abc import ABCMeta, abstractmethod

class Abstract(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def foo(self):
        print("tst")

a = Abstract()
a.foo()

当我执行这个模块时,控制台上的输出如下:

1
2
pydev debugger: starting (pid: 20388)
tst

与公认的答案相反

1
>>> TypeError: Can not instantiate abstract class Abstract with abstract methods foo

那么我在做什么对错呢?为什么工作不失败?感谢任何专家对此的洞察。


在python 3中,创建抽象基类时使用metaclass参数:

1
2
3
4
5
6
7
8
9
10
from abc import ABCMeta, abstractmethod

class Abstract(metaclass=ABCMeta):

    @abstractmethod
    def foo(self):
        print("tst")

a = Abstract()
a.foo()


在python2中,必须将元类指定为thusly:

1
2
3
4
5
6
7
8
9
10
11
import abc

class ABC(object):

    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def foo(self):
        return True

a = ABC()

它产生了一个TypeError

1
2
3
4
Traceback (most recent call last):
  File"<pyshell#59>", line 1, in <module>
    a = ABC()
TypeError: Can't instantiate abstract class ABC with abstract methods foo

但是在python3中,将__metaclass__指定为属性不起作用(正如您所希望的那样,但解释器并不认为它是错误,只是一个普通属性,这就是上面的代码不会引发错误的原因)。元类现在定义为类的命名参数:

1
2
3
4
5
6
7
8
9
import abc

class ABC(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def foo(self):
        return True

a = ABC()

提出TypeError

1
2
3
4
Traceback (most recent call last):
  File"main.py", line 11, in
    a = ABC()
TypeError: Can't instantiate abstract class ABC with abstract methods foo