TypeVar 的解释

2025-06-04

TypeVar 的解释

如果您完全不熟悉 Python 中的类型注释,我之前的文章应该可以帮助您入门。

在这篇文章中,我将向您展示如何使用类型变量(或TypeVars)来获得乐趣和利益。

问题

此函数接受任何参数并按原样返回。如何向类型检查器解释返回类型与 的类型相同arg



def identity(arg):
    return arg


Enter fullscreen mode Exit fullscreen mode

为什么不使用Any



def identity(arg: Any) -> Any:
    return arg


Enter fullscreen mode Exit fullscreen mode

如果使用Any,类型检查器将无法理解此函数的工作原理:就其本身而言,该函数可以返回任何值。返回类型与 的类型无关arg

我们确实希望numberint这里,以便类型检查器能够在下一行捕获错误:
使用简单注释进行类型推断

为什么不针对不同类型专门设计函数?



def identity_int(arg: int) -> int:
    return arg

def identity_str(arg: str) -> str:
    return arg

def identity_list_str(arg: list[str]) -> list[str]:
    return arg

...


Enter fullscreen mode Exit fullscreen mode
  1. 这扩展性不好。你要重复同样的功能 10 次吗?你会记得保持同步吗?

  2. 如果这是一个库函数怎么办?你无法预测人们会如何使用这个函数。

解决方案:类型变量

类型变量允许你将多个类型链接在一起。你可以这样使用类型变量来注释identity函数:



from typing import TypeVar

T = TypeVar("T")

def identity(arg: T) -> T:
    return arg


Enter fullscreen mode Exit fullscreen mode

这里返回类型与参数类型“链接”在一起:无论你把什么输入到函数中,都会得到相同的结果。

实际运行效果如下(在 VSCode 中使用 Pylance):

通用函数演示

对类型变量施加约束

这是一个类型良好的函数吗?



def triple(string: Union[str, bytes]) -> Union[str, bytes]:
    return string * 3


Enter fullscreen mode Exit fullscreen mode

并非如此:如果你传入一个字符串,你得到的永远是一个字符串,字节数也一样。这会给你带来一些麻烦,因为知道什么时候会得到一个str,什么时候会得到一个bytes反义词。
错误演示

“如果你传入str,你就会得到str。如果你传入bytes,你就会得到bytes”——听起来像是类型变量的工作。

错误演示

这很合理——并非所有类型都支持乘法。我们可以限制我们的类型变量只能接受str“或” bytes(当然,也包括它们的子类)。



AnyString = TypeVar("AnyString", str, bytes)

def triple(string: AnyString) -> AnyString:
    return string * 3

unicode_scream = triple("A") + "!"
bytes_scream = triple(b"A") + b"!"


Enter fullscreen mode Exit fullscreen mode

使用类型变量作为参数

您还可以使用类型变量作为泛型类型的参数,例如listIterable



def remove_falsey_from_list(items: list[T]) -> list[T]:
    return [item for item in items if item]

def remove_falsey(items: Iterable[T]) -> Iterator[T]:
    for item in items:
        if item:
            yield item


Enter fullscreen mode Exit fullscreen mode

然而,这很快就会变得棘手。我将在下一篇文章中深入探讨这个问题。

链接

文章来源:https://dev.to/decorator_factory/typevars-explained-hmo
PREV
作为一名 AWS 开发者倡导者,我学到了 10 件事简介背景提示 1:内部倡导与外部倡导提示 2:做笔记提示 3:执行提示 4:确定优先级、确定优先级并重新确定优先级提示 5:成为自己的制作人提示 6:时间和时区管理不善提示 7:保持真实提示 8:享受乐趣提示 9:重复使用和回收提示 10:始终寻求反馈/评论总结
NEXT
API 的类型 | 什么是 API? | 不同类型的 API 什么是 API? API 的类型