# Python 类型提示中的类型提升

在 Python 中,类型提示可以帮助开发者提高代码的可读性和可维护性,并允许类型检查器在运行时之前发现潜在的类型错误。然而,在某些情况下,函数的返回类型依赖于输入参数的类型,这就需要一种更高级的类型提示机制来实现类型提升。

考虑一个简单的例子,一个执行乘法运算的函数,它可以接受 `int` 或 `float` 类型的参数:

```python
def mul(a: int | float, b: int | float): # 返回类型?
return a * b

在这个例子中,如果 a 和 b 都是 int 类型,则函数返回 int 类型;否则,返回 float 类型。如何正确且简洁地注解这个函数的返回类型呢?

一种方法是使用 @overload 装饰器:

from typing import overload

@overload
def mul(a: int, b: int) -> int: ...

@overload
def mul(a: float, b: int | float) -> float: ...

@overload
def mul(a: int | float, b: float) -> float: ...

def mul(a, b):
    return a * b

这种方法虽然可行,但非常冗长,并且对于更复杂的类型组合,需要大量的重载。我们希望找到一种更简洁的方法,类似于 C++ 中的 SFINAE (Substitution failure is not an error)。

使用泛型和 TypeVar

我们可以尝试使用泛型和 TypeVar 来实现类型提升。以下是一个示例:

from typing import TypeVar, Generic

T1 = TypeVar('T1', str, float)
T2 = TypeVar('T2', str, float)

class Promoted(Generic[T1, T2]):
    def __class_getitem__(cls, types):
        t1, t2 = types
        if t1 == str or t2 == str:
            return str
        return float

def method(a: T1, b: T2) -> Promoted[T1, T2]:
    if isinstance(a, str) or isinstance(b, str):
        return f"{a} {b}"
    else:
        return a*b

result1 = method("Hello", "World")  # 应该被推断为 str
result2 = method(3.0, 4.0)  # 应该被推断为 float
result3 = method("Price", 5.0)  # 应该被推断为 str

在这个例子中,我们定义了一个 Promoted 类,它是一个泛型类,可以根据 T1 和 T2 的类型来返回不同的类型。__class_getitem__ 方法用于实现类型推断的逻辑。如果 T1 或 T2 中有任何一个是 str 类型,则返回 str 类型;否则,返回 float 类型。

method 函数接受 T1 和 T2 类型的参数,并返回 Promoted[T1, T2] 类型。

注意事项

虽然这种方法在理论上是可行的,但实际效果可能受到 IDE 的影响。在某些 IDE 中,类型提示可能无法正确地推断出 result1、result2 和 result3 的类型,而是将它们都提示为 "Promoted"。

总结

使用泛型和 TypeVar 可以实现类型提升,但实际效果可能受到 IDE 的影响。在选择类型提示方法时,需要权衡代码的简洁性和类型提示的准确性。对于简单的类型提升,可以使用 @overload 装饰器;对于更复杂的类型组合,可以尝试使用泛型和 TypeVar。

在实际应用中,应根据具体情况选择最合适的类型提示方法,并进行充分的测试,以确保代码的类型安全性。


以上就是# Python 类型提示中的类型提升的详细内容,更多请关注昆居客【www.kunjuke.com】。

相关推荐:

山灵 M7T Master Hi-Fi 播放器预热:动态范围 / 空间层次提升、UI 界面全新设计

感谢网友 不一样的体验 的线索投递! 7 月 5 日消息,山灵发文,预热旗下全新 Hi-Fi 播放器 M7T Master 即将上市,该机号称是“升维版”M7T,在声音素质方面有较大升级。外观方面,M7T Master 播放器在原有航空级工艺基础上,加入专属 Logo 定制,细节重新打磨,整机质感升级;UI 界面全新设计,触控更直观沉浸。同时,山灵称开发工程师在不大幅改动电路架构的前提下,通过深入...

动物大联盟新手战力提升攻略

动物大联盟新手战力怎么提升,前期打不过图的话可以在聊天频道或者加入公会,寻求大佬帮助。其次是可以通过氪金去提升战力,前期推荐新手成长武器礼包,里面可以领取1个古遗物礼盒。 动物大联盟新手战力提升攻略: 一、角色等级 完成主线任务、日常副本可以获得大量的角色经验值,进而快速提升角色等级。满级提供战斗力的同时解锁所有养成板块,可以进行其他板块的养成,尤其是解锁版本最新的副本,能获取大量资源; 前期打不...

AI 芯片新创 Etched 完成流片:低电压提升实际算力表现,SRAM + HBM 缓存

7 月 1 日消息,AI 芯片初创企业 Etched 当地时间昨日宣布其推理加速器芯片完成 A0 步进流片和首批机架构建。该企业获得超 10 亿美元订单和 8 亿美元 B 轮融资,首批机架产品预计 2026 年夏天出货。Etched 表示,现有 AI 芯片在高负载下会产生大量废热,引发频率下降,最终导致实际的推理吞吐量仅有理论峰值的一半不到。而 Etched 的台积电 N4P 制程工艺芯片采用了全...

实测:Steam Machine 加一条内存,性能最高提升 20%

7 月 1 日消息,Valve 的 Steam Machine 出厂仅搭载单条内存模组,正受到越来越多玩家与评测媒体的审视。早期实测数据显示,该硬件配置会拖累整机性能。跑分测试证明,只要加装第二条内存开启双通道模式,无论是压缩类工作负载还是多款主流 3A 游戏,性能都能获得肉眼可见的提升。据了解,零售版 Steam Machine 标配一根 16GB DDR5-5600 SO-DIMM 内存条,V...

《太吾绘卷:天幕心帷》提升生存能力方法介绍

《太吾绘卷:天幕心帷》中的提升生存能力是游戏里非常重要的事情,毕竟只有生存能力强才能不会被轻易干掉,而想要快速提升生存能力可以用一些技巧,首先是第一点还是提升命中和化解属性,化解属性能够让敌人的攻击力打一定折扣。 太吾绘卷天幕心帷怎么提升生存能力 本文内容来源于互联网,如有侵权请联系删除。

《归环》角色好感度提升攻略

归环角色好感度怎么提升?其实很多玩家在体验归环游戏时发现每天都去跟对应角色聊天,或者是背包,药水等等都送给对应的角色,但是好感度却并没有发生任何的改变,产生这样的情况,其实属于浪费时间跟材料。建议大家还是先了解清楚好感系统的规则,下面就重点给大家介绍好感度提升的方法。 《归环》角色好感度提升攻略 很多玩家在提升好感度时直接选择跟角色聊天,聊完之后就选择离开,却不知道同一个角色每天能触发三次独立的对...

幻塔拟态获取及提升方式

幻塔拟态如何获取,在卡池里抽取武器,抽中SR或者SSR都会给一个拟态,拟态相当于皮肤外观,拟态作为游戏里既好看又实用的功能,在增补玩家战斗力的同时,也带来了好看的造型,让玩家摆脱时装太少的尴尬。 幻塔拟态获取及提升方式: 1、拟态获取方式 在卡池里抽取武器,抽中SR或者SSR都会给一个拟态,拟态相当于皮肤外观,你可以理解成抽出了一个角色,但也不算职业类型的。 2、造型的切换 切换造型的地方就在【时...

最强祖师韩立本命原胚类型推荐

最强祖师韩立本命原胚怎么选,当前版本的原胚共有十四种类型,法宝材料更是有二十种之多,想要为弟子选择合适的原胚类型及配方材料就必须要清楚该弟子的定位及需求。下面为大家分享最强祖师韩立本命原胚类型及配方选择。 最强祖师韩立本命原胚类型推荐: 一、韩立 1、本命胚类型选择 当前版本韩立玩法基本都是速攻,因此最适配韩立的原胚只有[无常印胚]。 二、本命胚配方材料选择 1、四阶水系法宝+叶子(2-4阶都可)...