如何阻止一个没有抽象方法的Python类被示例化?

bvjxkvbb  于 2023-03-31  发布在  Python
关注(0)|答案(1)|浏览(147)

下面的代码:

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会引发异常?

nbewdwxp

nbewdwxp1#

这里有一个方法:

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"}

在上面的例子中,如果你试图创建CategoryCategoryGroup对象,你会得到一个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

相关问题