我一直认为,当一个人不想实例化该类时,应该继承自abc.ABC
。但是我刚刚意识到,如果一类有一个@abstractmethod
,那么一个人也无法实例化它。
还有其他理由要继承ABC
吗?
答案 0 :(得分:5)
除非您将start microsoft-edge:http://www.example.com/
用作类的元类(显式或继承自abc.ABCMeta
),否则使用abc.ABC
并不会做任何事情。
abstractmethod
同样,除非您将至少一种方法标记为抽象,否则使用>>> from abc import abstractmethod, ABC
>>> class Foo:
... @abstractmethod
... def bar(self):
... pass
...
>>> f = Foo()
>>>
并没有多大意义:
ABCMeta
这是两者的结合,使得一个类(名义上)无法实例化:
>>> class Bar(ABC):
... pass
...
>>> b = Bar()
>>>
(即使如此,请注意,所有>>> class Baz(ABC):
... @abstractmethod
... def m(self):
... pass
...
>>> b = Baz()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Baz with abstract methods m
>>>
所做的都是将修饰的方法添加到元类机制在尝试实例化该类时要查询的集合。要破坏该机制很简单:
@abstractmethod
)
请注意,>>> Baz.__abstractmethods__
frozenset({'m'})
>>> Baz.__abstractmethods__ = set()
>>> b = Baz()
>>>
本身是一个琐碎的类,它使用ABC
作为其元类,这使得其任何后代也都使用它。
ABCMeta
答案 1 :(得分:0)
chepner所说的话,以及可读性。从ABC
继承可以使读者清楚地了解自己的工作。
>>> from abc import ABC, abstractmethod
>>>
>>> class Foo:
... @abstractmethod
... def f(self):
... pass
...
>>> class Bar(Foo):
... pass
...
>>> Bar().f()
>>>
>>> class Baz(ABC):
... @abstractmethod
... def f(self):
... pass
...
>>> class Quux(Baz):
... pass
...
>>> Quux().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Quux with abstract methods f