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

如何通过装饰器实现Python函数重复重载,保持代码简洁?

用装饰器复用函数重载逻辑(支持Python≥3.10)

核心概要(TLDR)

我希望通过指定函数重载来满足类型检查器的要求,但存在大量重复的函数签名,希望实现代码复用(DRY原则)。

示例与现有代码

我有多个函数,它们的第一个参数为int或float,且返回值类型与首参数一致。为让编辑器识别这种一一对应的类型关系,我手动添加了重载定义:

from typing import overload

@overload
def add_two(x: int) -> int: ...

@overload
def add_two(x: float) -> float: ...

def add_two(x: int | float) -> int | float:
    return x + 2

这种方式可行,但问题在于我有大量类似函数,例如:

def add_two(x: int | float) -> int | float:
    return x + 2

def square(x: int | float) -> int | float:
    return x ** 2

def multiply_by_int_add_int(x: int | float, y: int, z: int) -> int | float:
    return x * y + z

(...)

若为每个函数都添加上述重载定义,会产生大量重复代码。

问题

是否可以编写一个装饰器,将其应用到每个函数定义上以实现上述重载逻辑?

注意:

  • 这些函数的共同点是:第一个参数的类型决定了返回值的类型。
  • 其余参数的数量和类型不固定。

当前尝试

import functools
from typing import Callable, ParamSpec, TypeVar, overload

T = TypeVar("T")
P = ParamSpec("P")


def int2int_and_float2float(fn: Callable[P, T]) -> Callable[P, T]:

    @overload
    def wrapped(x: int, *args, **kwargs) -> int: ...

    @overload
    def wrapped(x: float, *args, **kwargs) -> float: ...

    @functools.wraps(fn)
    def wrapped(*args: P.args, **kwargs: P.kwargs):
        return fn(*args, **kwargs)

    return wrapped

@int2int_and_float2float
def add_two(x: int | float) -> int | float:
    """Add two"""
    return x * 2

该尝试未生效:add_two(3)的返回值未被识别为整数。

我忽略了哪些要点?

(需支持Python >=3.10版本)


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:53:09