
在这个例子中,如果 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 来实现类型提升。以下是一个示例:
立即学习“Python免费学习笔记(深入)”;
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 类型提示中的类型提升的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号