我有以下代码:
class Category(abc.ABC):
foo = {"bar"}
尽管继承自
abc.ABC
,我可以实例化一个Category
就好了:
>>> a = Category()
>>>
而我希望它会引发如下错误。
>>> class Foo(abc.ABC):
... @abc.abstractmethod
... def bar(self):
... return "baz"
...
>>> f = Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Foo with abstract methods bar
>>>
看来这是因为
Category
没有抽象方法。我如何确保尝试实例化 Category
会引发异常?
这是一种方法:
from abc import ABC, ABCMeta
class Category(ABC):
foo = {"bar"}
def __new__(cls, *args, **kwargs):
if (cls.__base__ is ABC or cls.__class__ is ABCMeta):
raise TypeError(f"Can't instantiate abstract class {cls}")
return super().__new__(cls, *args, **kwargs)
如果您想在一些相关的抽象类之间共享此行为,这也可能会有所帮助。例如:
class CategoryGroup(ABC):
baz = {"qux"}
def __new__(cls, *args, **kwargs):
if (cls.__base__ is ABC or cls.__class__ is ABCMeta):
raise TypeError(f"Can't instantiate {cls.__name__}")
return super().__new__(cls, *args, **kwargs)
class Category(CategoryGroup, ABC):
foo = {"bar"}
在上面的示例中,如果您尝试创建
Category
或 CategoryGroup
对象,您将得到一个 TypeError,如下所示:
In [2]: CategoryGroup()
TypeError: Can't instantiate CategoryGroup
In [3]: Category()
TypeError: Can't instantiate Category
In [4]: Category.__base__
Out[4]: __main__.CategoryGroup