以前我创建抽象类或者接口的时候,通常会这样写:
class AbstractClass:
def method(self, arg: int) -> int:
raise NotImplementedError()
这么做会带来以下问题:
下面就介绍一下如何解决这两个问题。
Python 标准库提供了一个类abc.ABC
,如果一个类继承了abc.ABC
,那么这个类就是一个抽象类。我们可以使用@abc.abstractmethod
装饰器来标记一个方法是抽象方法。抽象类的子类必须实现所有抽象方法,否则在创建对象的时候就会报错。
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def method(self, arg: int) -> int:
...
class ConcreteClass(AbstractClass):
def method(self, arg: int) -> int:
return arg
c = ConcreteClass() # 没问题
a = AbstractClass() # 会得到 TypeError
从 Python 3.12 开始,typing
模块新增了一个@override
装饰器。这个装饰器可以提醒静态检查器这个方法必须覆盖父类的方法,并且方法签名必须一致。
from typing import override
class AbstractClass:
def method(self, arg: int) -> int:
raise NotImplementedError()
class ConcreteClass(AbstractClass):
@override
def method(self, arg: int) -> None: # 会引发静态检查器的警告
pass
如果是 Python 3.11 及以下的版本,可以用typing_extensions
模块提供的 backport。