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

Python中如何用Callable为相同签名的函数统一标注类型?

问题原因

你写的代码相当于在同一作用域下两次定义了同名变量f:第一次是标注类型时声明了变量f,第二次是def f定义函数时再次给f赋值,因此触发mypy的重复定义报错。Python 的def语句本身就是赋值操作,无法直接复用提前写好的变量类型标注。

实现方案

下面两种是常用的无侵入、兼容mypy的实现方案:

方案1:类型别名 + 函数赋值

提前给函数签名定义统一的类型别名,定义函数后再赋值给带类型标注的变量即可,mypy会自动校验函数实现是否符合签名要求:

from typing import Callable

# 统一定义函数签名的类型别名
IntBinaryOp = Callable[[int, int], int]

# 先定义函数
def _add(x, y):
    return x + y
# 赋值给带类型标注的变量,自动完成类型校验
add: IntBinaryOp = _add

def _multiply(x, y):
    return x * y
multiply: IntBinaryOp = _multiply

这种写法下mypy会自动校验函数参数、返回值是否匹配类型要求,调用时也会做类型检查。

方案2:类型标注装饰器

如果不想额外定义下划线开头的中转函数,可以写一个纯类型层面的装饰器,批量给同签名函数加类型:

from typing import Callable, TypeVar

IntBinaryOp = Callable[[int, int], int]
T = TypeVar("T", bound=Callable)

def with_type(func_type: T) -> Callable[[Callable], T]:
    # 运行时无任何逻辑,仅做类型传递
    def decorator(func: Callable) -> T:
        return func
    return decorator

# 直接用装饰器标注,不需要额外写参数返回值类型
@with_type(IntBinaryOp)
def add(x, y):
    return x + y

@with_type(IntBinaryOp)
def multiply(x, y):
    return x * y

这种写法更适合批量处理大量同签名函数,代码更简洁。Python 3.10及以上版本可以直接运行上述代码,低版本可以额外导入typing_extensions.TypeAlias标注类型别名提升兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:27:04