尽管使用abc,仍能实例化Python类
这是关于这个问题的回答,内容是“使用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()