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

如何为Python类型提升函数简洁精确标注返回类型?

实现类型提升的精确泛型类型标注

在Python类型系统中,虽无直接对应C++ SFINAE的特性,但可通过泛型TypeVar结合条件类型或类型检查器自动推断实现简洁的类型提升标注,同时保证返回类型精确。

方案1:简化版@overload + TypeVar约束

若觉得全量@overload过于冗长,可只针对核心分支重载,用泛型兜底:

from typing import TypeVar, overload

Num = TypeVar('Num', int, float)

@overload
def mul(a: int, b: int) -> int: ...
def mul(a: Num, b: Num) -> float:
    return a * b

仅需两个分支:一个处理双int输入(返回int),另一个覆盖所有其他数值组合(返回float),兼顾简洁性与类型精确性,类型检查器可准确推断返回类型。

方案2:条件类型(需mypy 0.910+支持)

借助mypy的条件类型特性,直接描述类型提升规则,无需显式写@overload:

from typing import TypeVar, TypeAlias
from typing_extensions import TypeIs

T = TypeVar('T', int, float)
U = TypeVar('U', int, float)

# 定义提升规则:仅当两参数均为int时返回int,否则返回float
PromotedType: TypeAlias = int if (TypeIs[T, int] and TypeIs[U, int]) else float

def mul(a: T, b: U) -> PromotedType:
    return a * b

这种写法接近你想要的promote_types(T1, T2)风格,通过条件类型直接映射输入与返回类型的关系。

方案3:自定义类型提升协议(复杂场景适用)

若实际场景涉及更复杂的类型体系,可通过Protocol定义可提升类型,结合泛型实现通用逻辑:

from typing import TypeVar, Protocol, runtime_checkable

@runtime_checkable
class Numeric(Protocol):
    def __mul__(self, other: 'Numeric') -> 'Numeric': ...

T = TypeVar('T', bound=Numeric)
U = TypeVar('U', bound=Numeric)

def promote_types(t: type[T], u: type[U]) -> type:
    if t is int and u is int:
        return int
    return float

def mul(a: T, b: U) -> promote_types(type(a), type(b)):
    return a * b

该方案扩展性强,可根据自定义类型体系灵活调整promote_types的逻辑,保持代码简洁性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:57:35