【问题标题】:What the code '_T = TypeVar('_T')' means in a *.pyi file?*.pyi 文件中的代码 '_T = TypeVar('_T')' 是什么意思?
【发布时间】:2019-12-24 09:18:13
【问题描述】:

我是 Python 注释的新手(类型提示)。我注意到pyi 文件中的许多类定义都继承了Generic[_T]_T = TypeVar('_T')

我一头雾水,这里的_T是什么意思?

from typing import Generic, TypeVar

_T = TypeVar('_T')

class Base(Generic[_T]): pass

【问题讨论】:

  • _ 只是表示该变量是受保护的类型。
  • python 不支持对 java 等变量的保护,但约定使用 _ 作为开发者约定

标签: python annotations type-hinting pyi


【解决方案1】:

我建议通读整个built-in typing module documentation


typing.TypeVar

基本用法

具体来说,typing.TypeVar 用于指定允许多种可能的类型。如果没有指定具体的类型,那么任何类型都是有效的。

from typing import TypeVar

T = TypeVar('T')            # <-- 'T' can be any type
A = TypeVar('A', str, int)  # <-- 'A' will be either str or int

但是,如果 T 可以是任何类型,那么为什么要创建这样的 typing.TypeVar,而您可以只使用 typing.Any 作为类型提示呢?

原因是您可以确保特定的输入和输出参数具有相同的类型,如下例所示。

字典查找示例

from typing import TypeVar, Dict
Key = TypeVar('Key')
Value = TypeVar('Value')

def lookup(input_dict: Dict[Key, Value], key_to_lookup: Key) -> Value:
    return input_dict[key_to_loopup]

起初这似乎是一个微不足道的例子,但这些注释要求输入字典中键的类型与 key_to_lookup 参数的类型相同,并且输出的类型与中的值的类型匹配字典也是。

键和值作为一个整体可以是不同的类型,并且对于任何对该函数的特定调用,它们可能是不同的(因为键和值不限制类型),但是对于给定的调用, dict 必须匹配查找键的类型,并且值和返回类型相同。

加法示例

如果您创建一个新的 TypeVar 并将类型限制为 float 和 int:

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

def add_x_and_y(x: B, y: B) -> B:
    return x + y

这个函数要求 x 和 y 要么都是 float,要么都是 int,并且必须返回相同的类型。如果 x 是 float 而 y 是 int,则类型检查应该失败。


typing.Generic

我对这个有点粗略,但是typing.Generic(官方文档的链接)抽象基类(ABC)允许设置一个具有定义类型提示的类。他们在链接的文档中有一个很好的例子。

在这种情况下,他们正在创建一个完全通用的类型类。如果我理解正确,这允许在代码的其他地方使用Base[AnyName] 作为类型提示,然后可以重用AnyName 在同一定义中的其他地方(即在同一代码范围内)表示相同的类型。

我想这对于避免重复使用TypeVar 很有用,您基本上可以通过使用 Base 类作为类型提示来随意创建新的 TypeVars,只要您只需要它的范围本地定义。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多