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

如何让Python函数与另一个函数拥有相同的类型标注?

实现包装器的自动类型同步

1. 完全复制原函数的参数与返回类型

如果包装器只是原函数的简单转发,不需要修改返回值,可以通过PEP 612引入的ParamSpec和ReturnType自动复用原函数的类型签名,无需硬编码。

示例代码:

from typing import ParamSpec, ReturnType, cast
import os

# 定义参数规格和返回值类型变量
P = ParamSpec("P")
R = ReturnType("R")

def my_open(*args: P.args, **kwargs: P.kwargs) -> R:
    # 用cast辅助类型检查器确认返回值类型匹配
    return cast(R, os.open(*args, **kwargs))

若包装器无额外逻辑,还能更简洁:

from typing import Callable, ParamSpec, ReturnType
import os

P = ParamSpec("P")
R = ReturnType("R")

my_open: Callable[P, R] = os.open

2. 保留参数类型,修改返回类型

对于像scoped_open这类需要保留原函数参数、但返回类型不同的场景,同样用ParamSpec捕获参数类型,ReturnType捕获原函数返回值类型,再组合成新的返回类型。

示例代码:

from typing import ParamSpec, ReturnType, Generator, contextmanager
import os

P = ParamSpec("P")
R = ReturnType("R")

@contextmanager
def scoped_open(*args: P.args, **kwargs: P.kwargs) -> Generator[R, None, None]:
    fd = os.open(*args, **kwargs)
    try:
        yield fd
    finally:
        os.close(fd)

这里Generator[R, None, None]表示生成器会产出os.open的返回值类型,不接收外部值,也无最终返回值,完全符合上下文管理器的类型要求。

工具支持情况

  • Pyright:完全支持PEP 612,无需额外配置。
  • Mypy:从0.800版本开始支持,确保使用足够新的版本即可。

这种方式的核心优势是,原函数(比如os.open)的类型签名随版本更新时,包装器的类型会自动同步,无需手动修改标注。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:00:07