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

如何为将int转换为str的Python装饰器添加正确类型提示?

为参数转换装饰器添加类型提示

要让mypy正确识别装饰器将int参数转为str的行为,需要结合Python的类型提示工具(如ParamSpec、TypeVar、TypeVarTuple等)来精确标注装饰器的输入输出类型。以下是两种可行的实现方案:

方案1:针对任意参数数量的通用实现(Python 3.11+)

使用TypeVarTuple和Unpack处理任意数量的参数,将每个原参数类型扩展为原类型 | int,确保mypy能识别调用时传入int是合法的:

from typing import Callable, TypeVarTuple, Unpack, TypeVar, Union, Any

# 定义类型变量:捕获原函数的参数类型元组和返回值类型
Args = TypeVarTuple("Args")
R = TypeVar("R")

def convert_int_to_str(
    func: Callable[[Unpack[Args]], R]
) -> Callable[[Unpack[tuple[Union[Arg, int] for Arg in Args]]], R]:
    def wrapper(
        *args: Unpack[tuple[Union[Arg, int] for Arg in Args]],
        **kwargs: Any
    ) -> R:
        # 将位置参数中的int转为str
        converted_args = tuple(str(arg) if isinstance(arg, int) else arg for arg in args)
        # 将关键字参数中的int转为str
        converted_kwargs = {
            key: str(value) if isinstance(value, int) else value
            for key, value in kwargs.items()
        }
        return func(*converted_args, **converted_kwargs)
    return wrapper

使用示例

@convert_int_to_str
def foo(x: str) -> str:
    return f"foo{x}"

# mypy不会报错,因为装饰后的函数接受int或str
print(foo(4))  # 输出 'foo4'

@convert_int_to_str
def bar(a: str, b: str) -> str:
    return f"{a}{b}"

bar(1, "2")  # 输出 '12',mypy识别合法

方案2:针对固定参数数量的重载实现(兼容旧Python版本)

如果使用Python 3.10及以下版本,无法使用TypeVarTuple,可以通过@overload为不同参数数量的函数分别标注类型:

from typing import Callable, TypeVar, overload

R = TypeVar("R")
StrOrInt = TypeVar("StrOrInt", str, int)

# 重载:单参数函数
@overload
def convert_int_to_str(func: Callable[[str], R]) -> Callable[[StrOrInt], R]:
    ...

# 重载:双参数函数
@overload
def convert_int_to_str(func: Callable[[str, str], R]) -> Callable[[StrOrInt, StrOrInt], R]:
    ...

# 通用实现
def convert_int_to_str(func: Callable[..., R]) -> Callable[..., R]:
    def wrapper(*args, **kwargs) -> R:
        converted_args = tuple(str(arg) if isinstance(arg, int) else arg for arg in args)
        converted_kwargs = {k: str(v) if isinstance(v, int) else v for k, v in kwargs.items()}
        return func(*converted_args, **converted_kwargs)
    return wrapper

关键说明

  • 两种方案的核心都是告诉mypy:装饰后的函数允许接受int类型参数,这些参数会被自动转为str,符合原函数的参数要求。
  • 方案1更灵活,支持任意数量的参数,但需要Python 3.11+;方案2通过重载兼容旧版本,但需要手动添加对应参数数量的重载标注。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:26:02