尽管使用abc,仍能实例化Python类

10 投票
2 回答
2641 浏览
提问于 2025-04-18 09:53

这是关于这个问题的回答,内容是“使用Python的abc模块来创建抽象类。”(由@alexvassel提供,并被接受为答案)。

我尝试了这些建议,但奇怪的是,尽管我按照建议使用了abc的方法,结果却不奏效。所以我在这里发帖提问:

这是我的Python代码:

from abc import ABCMeta, abstractmethod

class Abstract(object):
    __metaclass__ = ABCMeta

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

a = Abstract()
a.foo()

当我执行这个模块时,我在控制台上看到的输出是:

pydev debugger: starting (pid: 20388)
tst

与那个被接受的答案相比

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

那么我到底做对了什么或做错了什么呢?为什么会这样工作而不是失败?希望能得到专家的见解。

2 个回答

6

在Python 2中,你必须这样来指定元类:

import abc

class ABC(object):

    __metaclass__ = abc.ABCMeta

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

a = ABC()

这会引发一个 TypeError 错误。

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

但是在Python 3中,把 __metaclass__ 作为一个属性来指定是行不通的(虽然你是这么想的,但解释器并不把它当成错误,只是把它当作其他普通属性,所以上面的代码不会引发错误)。在Python 3中,元类现在是作为类的一个命名参数来定义的:

import abc

class ABC(metaclass=abc.ABCMeta):

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

a = ABC()

这会引发 TypeError 错误:

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

在Python 3中,创建抽象基类时,可以使用metaclass这个参数:

from abc import ABCMeta, abstractmethod

class Abstract(metaclass=ABCMeta):

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

a = Abstract()
a.foo()

撰写回答