【问题标题】:Using List/Tuple/etc. from typing vs directly referring type as list/tuple/etc使用列表/元组/等。从键入与直接将类型引用为列表/元组/等
【发布时间】:2017-01-20 08:33:12
【问题描述】:

typing模块中使用ListTuple等有什么区别:

from typing import Tuple

def f(points: Tuple):
    return map(do_stuff, points)

相对于直接引用 Python 的类型:

def f(points: tuple):
    return map(do_stuff, points)

我什么时候应该使用一个而不是另一个?

【问题讨论】:

标签: python type-hinting python-typing


【解决方案1】:

在 Python 3.9 added support for type hinting using standard collections 之前,如果您想记录容器的内容 类型,则必须使用 typing.Tupletyping.List

def f(points: Tuple[float, float]):
    return map(do_stuff, points)

直到 Python 3.8,tuplelist 不支持成为 used as generic types。上面的示例记录了函数f 要求points 参数是具有两个float 值的元组。

typing.Tuple 在这里的特殊之处在于它允许您指定特定数量的预期元素和每个位置的类型。如果未设置长度且应重复类型,请使用省略号:Tuple[float, ...] 描述了可变长度 tuplefloats。

对于typing.List 和其他序列类型,您通常只指定所有元素的类型; List[str] 是任意大小的字符串列表。请注意,函数应优先将typing.Sequence 作为参数,typing.List 通常仅用于返回类型;一般来说,大多数函数会采用任何序列并且只进行迭代,但是当您返回 list 时,您实际上是在返回一个特定的、可变的序列类型。

如果您仍需要支持 Python 3.8 或更早版本的代码,您应该始终选择 typing 泛型,即使您当前没有限制内容。稍后使用泛型类型添加该约束会更容易,因为结果更改会更小。

如果您正在实现自定义容器类型并希望该类型支持泛型,您可以implement a __class_getitem__ hook 或从typing.Generic 继承(反过来实现__class_getitem__)。

【讨论】:

  • List[] 相对于 [] 的优势如何。如果个人觉得第一个更好,但我在代码审查中没有论据例如:)
  • @Samos 两者都将使用PEP 3107,但PEP 484the extension PEPs 中没有描述[]。如果不遵循标准,您将无法获得遵循标准的工具的好处。例如。 mypy 可能无法正常工作。
  • "请注意,函数应优先采用 typing.Sequence 作为参数,而 typing.List 通常仅用于返回类型;一般来说,大多数函数将采用任意序列并且仅进行迭代,但是当您返回列表时,你真的在​​返回一个特定的、可变的序列类型。”为什么函数不应该返回一个序列?
  • @kolistivra:因为这限制了调用者可以对返回的列表对象执行的操作。任何需要,比如说,一个 mutable 序列的东西都不会接受返回值。或者,如果出于某种原因特别需要列表,您也可以使用返回值。尽可能具体地设置您的返回值。
  • 别忘了from typing import Tuple
【解决方案2】:

从 Python 3.9 (PEP 585) 开始,tuplelist 和其他各种类现在都是泛型类型。现在首选使用这些而不是它们的 typing 对应项。从 Python 3.9 开始,您现在可以这样做:

def f(points: tuple[float, float]):
    return map(do_stuff, points)

如果您不需要评估您的类型提示,那么由于PEP 563,您可以在 Python 3.7+ 中使用此语法。

from __future__ import annotations


def f(points: tuple[float, float]):
    return map(do_stuff, points)

您应该尽可能选择非typing 泛型,因为旧的typing.Tupletyping.Listother generics 已弃用,并将在更高版本的 Python 中删除。

不推荐从typing 导入那些。由于PEP 563 以及尽量减少键入对运行时的影响的意图,此弃用不会产生 DeprecationWarnings。相反,当被检查程序的目标版本被通知为 Python 3.9 或更高版本时,类型检查器可能会警告这种不推荐使用的用法。建议允许在整个项目范围内消除这些警告。

在 Python 3.9.0 发布 5 年后发布的第一个 Python 版本中,将从类型模块中删除已弃用的功能。

【讨论】:

  • “现在首选使用这些而不是打字对应物。” 对于公共 python 库,继续使用 typing 泛型 4 年是否有意义Python 3.9.0 发布后?
  • 不反对@MateenUlhaq,但你能分享一下为什么它有意义吗?
  • @MonkeySeeMonkeyDo 所以这些库在 Python 3.0+ 上工作。虽然您可以手动执行 __future__.annotations 所做的事情 (def f(points: "tuple[float, float]")),但如果您需要在运行时评估类型提示,代码将无法工作。
猜你喜欢
  • 2018-08-24
  • 2012-10-31
  • 2015-05-11
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多