正如@SUTerliakov在评论中指出的那样,目前没有直接支持的方法来使用与父类覆盖方法相同的注释来注释子方法。
然而,随着Python 3.10中typing.ParamSpec的引入,一个可行的解决方法是定义一个包装函数,该函数使用父函数对象的参数规范来注释一个内部包装函数,该内部包装函数在对参数进行“一些处理”后实际调用父函数,并返回内部包装函数以使其成为子类的实际方法:
from typing import TypeVar, ParamSpec
from collections.abc import Callable
T = TypeVar('T')
P = ParamSpec('P')
class A:
def test(self, value: int, *args: str, **kwargs: int) -> str:
print('base method with:', self, value, args, kwargs)
return ' '.join(map(str, (value, args, kwargs)))
class B(A):
@staticmethod
def inherit(f: Callable[P, T]) -> Callable[P, T]:
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
print('do something in wrapper with:', args, kwargs)
return f(*args, **kwargs)
return wrapper
test = inherit(A.test)
print(B().test(1, 'foo', 'bar', a=2))
代码通过mypy的演示:https://mypy-play.net/?mypy=latest&python=3.11&gist=828b3ba31c5c4979ff46ae2b2213dbc4
代码在repl.it上运行的演示:https://replit.com/@blhsing/ThriftyZealousCustomer
PyCharm中类型提示的演示:
B.test
放在一个if not typing.TYPE_CHECKING
块下。 - dROOOzeParamSpec
来完成一些工作。 - blhsing