You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.9中泛型可调用类型缩小时报错的原因与解决办法

问题解答

错误原因

Python 3.10 开始,内置typing模块支持泛型别名的参数化语法——你可以直接用[]给自定义泛型别名传递参数列表(比如FunctionOrCoroutine[[], str]),这是对相关PEP规范的实现。但在Python 3.9中,typing-extensions里的ParamSpec还不兼容这种简化写法,它要求传递给泛型的参数必须是合法的类型对象,而[]本身不是类型,因此触发TypeError。

解决方法

方案1:显式写出具体类型(最简便)

绕开自定义泛型别名的参数化,直接在注解里写出完整的Union类型:

from typing_extensions import Callable, Awaitable, Union

def foo(callback_fn: Union[Callable[[], str], Callable[[], Awaitable[str]]]):
    pass

方案2:预定义对应参数签名的ParamSpec

先构造一个匹配无参数签名的ParamSpec实例,再传递给你的泛型别名:

from typing_extensions import ParamSpec, TypeVar, Callable, Awaitable, Union

_P = ParamSpec("_P")
_R = TypeVar("_R")
FunctionOrCoroutine = Union[Callable[_P, _R], Callable[_P, Awaitable[_R]]]

# 定义无参数的ParamSpec实例
_NoArgs = ParamSpec("_NoArgs")
_NoArgs.args = ()
_NoArgs.kwargs = {}

def foo(callback_fn: FunctionOrCoroutine[_NoArgs, str]):
    pass

方案3:升级到Python 3.10+(彻底解决)

如果项目环境允许,直接升级到Python 3.10或更高版本,就能直接使用你原本的写法,无需修改代码。

内容的提问来源于stack exchange,提问作者Carter Tinney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:33:31