字面量省略号作为Concatenate的最后参数是否合法?
Concatenate中省略号(...)用法的疑问与解析
问题背景
Python官方文档提到:> Concatenate的最后一个参数必须是ParamSpec或省略号(...)
但实际使用mypy检查包含该写法的代码时会报错,示例代码如下:
from typing import Callable, ParamSpec, Concatenate, TypeVar, Generic _P = ParamSpec('_P') _T = TypeVar('_T') class Test(Generic[_P, _T]): fn: Callable[Concatenate[_P, ...], _T]
对应的报错信息:
E: Unexpected "..." [misc] E: The last parameter to Concatenate needs to be a ParamSpec [valid-type]
问题解析
文档表述存在偏差
PEP 612(定义Concatenate的官方规范)中完全没有提及省略号的用法,当前主流类型检查器(如mypy)也不支持这种写法。文档里的描述大概率是混淆了Callable和Concatenate的用法——省略号在Callable中用来表示“任意数量的额外位置参数”,但Concatenate的设计初衷是拼接固定参数列表与ParamSpec,其最后一个参数必须是ParamSpec类型。未来语法的超前表述
相关讨论提到省略号在Concatenate中的用法属于计划中的未来语法,但当前稳定版本的类型检查器均未实现该功能,因此文档的描述属于超前性的错误表述,不具备可操作性。
正确写法示例
如果需要表示“拼接已有参数规格与其他参数”,应使用ParamSpec作为Concatenate的最后一个参数,示例如下:
from typing import Callable, ParamSpec, Concatenate, TypeVar, Generic _P = ParamSpec('_P') _ExtraParams = ParamSpec('_ExtraParams') _T = TypeVar('_T') class Test(Generic[_P, _ExtraParams, _T]): # 表示函数先接受_P定义的参数,再接受_ExtraParams定义的参数,返回_T类型 fn: Callable[Concatenate[_P, _ExtraParams], _T]
或者如果是要给已有参数规格添加固定前缀参数:
from typing import Callable, ParamSpec, Concatenate, TypeVar, Generic _P = ParamSpec('_P') _T = TypeVar('_T') class Test(Generic[_P, _T]): # 表示函数先接受一个int类型参数,再接受_P定义的参数,返回_T类型 fn: Callable[Concatenate[int, _P], _T]
内容的提问来源于stack exchange,提问作者STerliakov
相关产品推荐
相关产品推荐

