为什么如何使用 ABCMeta 和 abstractmethod

抽象基类(ABCs)强制派生类从基类实现特定方法。

要了解这是如何工作的以及为什么要使用它,让我们来看看 Van Rossum 会喜欢的一个例子。假设我们有一个 Base 类 MontyPython,它有两个必须由所有派生类实现的方法(笑话和妙语)。

class MontyPython:
    def joke(self):
        raise NotImplementedError()

    def punchline(self):
        raise NotImplementedError()

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

当我们实例化一个对象并调用它的两个方法时,我们将使用 punchline() 方法得到一个错误(如预期的那样)。

 >>> sketch = ArgumentClinic() 
 >>> sketch.punchline() 
NotImplementedError 

但是,这仍然允许我们实例化 ArgumentClinic 类的对象而不会出现错误。实际上,在我们查找 punchline() 之前,我们不会收到错误。

通过使用抽象基类(ABC)模块可以避免这种情况。让我们看看这是如何使用相同的例子:

from abc import ABCMeta, abstractmethod

class MontyPython(metaclass=ABCMeta):
    @abstractmethod
    def joke(self):
        pass

@abstractmethod
def punchline(self):
    pass

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

这次当我们尝试从不完整的类中实例化一个对象时,我们立即得到一个 TypeError!

>>> c = ArgumentClinic()
TypeError:
"Can't instantiate abstract class ArgumentClinic with abstract methods punchline"

在这种情况下,很容易完成类以避免任何 TypeErrors:

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

    def punchline(self):
        return "Send in the constable!"

这次当你实例化一个对象时,它的工作原理!