【问题标题】:How to properly function annotate / type hint a list of strings如何正确运行注释/类型提示字符串列表
【发布时间】:2015-11-01 13:02:33
【问题描述】:

我试图弄清楚如何正确地对字符串列表进行注释或键入提示。例如,如果我有这样的功能:

def send_email(self, from_address: str, to_addresses: list[str]):
    pass

to_addresses 应该是一个字符串列表。但是当我尝试使用该注释时,我的 Python 3.4.3 解释器中出现以下错误:

TypeError: 'type' object is not subscriptable

我很肯定 list[str] 会导致问题,因为如果我将其更改为 str,错误就会消失,但这并不能正确反映我对参数的意图。

【问题讨论】:

  • 字符串列表?如果它是一个 unicode 对象列表,或者一个从字符串派生的类呢?
  • 我想提示一个原始 str 类型的列表。如果是其中之一,我将无法处理。
  • 很遗憾,无法检查。您要问的实际上是遍历列表中的所有对象并验证它们是否为str。工作量太大了。 python 是鸭子类型的,因此您通常不应该依赖对象的实际类型。是的,我承认这有点荒谬,但如果你不喜欢它,你应该使用一些带有类型系统的语言。
  • 我不是要求对其进行检查,我只是真的要求对其进行适当的提示。我知道在 3.4 中没有静态类型或类型检查......我只想正确注释它。
  • 然后写入文档字符串。

标签: python


【解决方案1】:

Python 3.4 没有为其函数注解指定格式,它只是提供了一种机制,允许您使用任何表达式作为注解。如何解释注释取决于您和您使用的库。

Python 3.5 标准化了函数注释用于类型提示的方式,如 PEP 484 中所述。要注释字符串列表,请使用List[str],其中List 是从typing 模块导入的。如果你的函数接受任何类似列表的序列,你也可以使用Sequence[str],或者任何可迭代的使用Iterable[str]

从 Python 3.9 开始,您可以使用 list[str] 作为类型注释,不需要导入任何内容。

【讨论】:

  • 感谢您提供有意义且描述性的回复。如果它没有指定格式并允许任何表达式,为什么 list[str] 会失败?
  • @gnychis 它尝试评估表达式list[str],并尝试下标list,这是一种类型,不能下标。
  • 我应该使用其他可以下标和有意义的东西吗?
  • @您可以使用自己的有效表达式注解(例如[str]),尽管这将是非标准的,或者您可以使用typing 模块的反向移植(github.com/JukkaL/typing ),或使用另一个类型注释库,例如 mypy(它使用与 Python 3.5 类似的格式,并为您进行检查)。
  • 官方 backport 在 python 包索引上可用:pypi.python.org/pypi/typing
【解决方案2】:

在 Python 3.9+ 中,list(带有小写的 l)可用于类型注释,您的代码应该可以正常工作。在旧版本的 Python 上,您需要导入 typing.List 并改用它

from typing import List

to_addresses: List[str]

注意大写L

您可能需要考虑更具体的内容。为什么from_addressstr,而to_addresseslist[str]?也许是一个

import typing
Address = typing.NewType("Address")

会有帮助的。

【讨论】:

  • "为什么 from_address 是一个 str,而 to_addresses 是一个 list[str]?"因为您可以send an email to multiple addresses,但您不能在“发件人:”字段中输入多个电子邮件。
【解决方案3】:

此语法现在在Python 3.9+ 中有效:

在类型注释中,您现在可以使用内置集合类型,例如 listdict 作为泛型类型,而不是从 typing 导入相应的大写类型(例如 ListDict)。

但在 3.9 之前,您需要使用导入的 Listin Python 3.7+ 可以添加

from __future__ import annotations

在文件的顶部,允许使用list[int](例如)。

【讨论】:

  • 在 Python 3.8 中,您可以使用 from __future__ import annotations 启用此行为。否则,您将无法使用 typing.List
  • @BallpointBen 不,它不适用于3.8.5,在此导入后Vector = list[float] 仍然出现“'type' object is not subscriptable”错误。
  • @asuka 您只能将该语法用作类型注释,而不是用作值。
  • Nvm,我好像错了。 annotations 似乎确实允许 list[int]
  • @BallpointBen 谢谢!我误解了,现在它可以完美地工作了。
猜你喜欢
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多