重载函数无法接收所有参数:我的函数签名哪里有误?
@overload
def lazystr(func: str, *args: Any, **kwargs: Any) -> str:
...
def lazystr(
func: Callable[_P, str] | str,
*args: _P.args | Any,
**kwargs: _P.kwargs | Any,
) -> LazyString | str:
# 实际实现逻辑示例
if isinstance(func, str):
return func % args if args else func
else:
return LazyString()
## 写法二:用宽泛参数类型+内部类型窄化 这种写法更简洁,利用mypy的类型推断在函数内部分支做类型窄化: ```python from collections.abc import Callable from typing import ParamSpec, overload _P = ParamSpec("_P") class LazyString: ... @overload def lazystr(func: Callable[_P, str], *args: _P.args, **kwargs: _P.kwargs) -> LazyString: ... @overload def lazystr(func: str, *args: object, **kwargs: object) -> str: ... def lazystr( func: Callable[_P, str] | str, *args: object, **kwargs: object, ) -> LazyString | str: if isinstance(func, str): # 处理字符串分支,mypy会自动识别此时func是str类型 return func % (args + tuple(kwargs.values())) if args or kwargs else func else: # 处理Callable分支,mypy会自动推断args/kwargs符合_P的参数规格 return LazyString()
关键提醒
重载实现的参数必须能兼容所有重载签名的输入,mypy在这方面的检查比pyright严格得多。当func是str时,第二个重载允许任意参数,所以实现里的*args和**kwargs不能被限制为_P.args/_P.kwargs——毕竟_P只对应Callable场景的参数规格,和字符串场景不沾边。
内容的提问来源于stack exchange,提问作者shadowtalker
相关产品推荐
相关产品推荐

