指定类型集合的类型提示

334 投票
5 回答
339033 浏览
提问于 2025-04-18 14:02

在Python 3中,我们可以使用函数注解来指定一个列表(或者其他集合)里面的元素类型,这样在PyCharm和其他开发工具中就能提供类型提示。

下面是一个关于整型列表的伪代码示例:

def my_func(l:list<int>):
    pass

我知道可以通过文档字符串来实现这个功能...

def my_func(l):
    """
    :type l: list[int]
    """
    pass

...但如果可以的话,我更喜欢使用注解的方式。

5 个回答

4

在BDFL的支持下,几乎可以肯定,Python(可能是3.5版本)将通过函数注解提供一种标准的类型提示语法。

https://www.python.org/dev/peps/pep-0484/

在PEP中提到,有一个实验性的类型检查工具(有点像pylint,但专门检查类型)叫做mypy,它已经在使用这个标准,而且不需要任何新的语法。

http://mypy-lang.org/

60

类型注释是在 PEP 484 这个提案中加入的。

from . import Monitor
from typing import List, Set, Tuple, Dict


active_monitors = [] # type: List[Monitor]
# or
active_monitors: List[Monitor] = []

# bonus
active_monitors: Set[Monitor] = set()
monitor_pair: Tuple[Monitor, Monitor] = (Monitor(), Monitor())
monitor_dict: Dict[str, Monitor] = {'codename': Monitor()}

# nested
monitor_pair_list: List[Dict[str, Monitor]] = [{'codename': Monitor()}]

我现在在 PyCharm 上用 Python 3.6.4 运行这个是没问题的。

在Pycharm中的示例图片

198

从Python 3.9开始,内置类型在类型注解方面变得更加通用(具体可以参考PEP 585)。这意味着你可以直接指定元素的类型:

def my_func(l: list[int]):
    pass

这种变化也适用于标准库中的大多数其他容器类型,比如collections.dequecollections.abc.Mapping


一些工具可能在Python 3.9之前就支持这种语法。当注解在运行时不被检查时,可以使用引号或__future__.annotations来有效使用这种语法。

# quoted
def my_func(l: 'list[int]'):
    pass
# postponed evaluation of annotation
from __future__ import annotations

def my_func(l: list[int]):
    pass

由于PEP 585的影响,typing模块中与标准库类型对应的大多数辅助工具已经被弃用,比如typing.Listtyping.Dequetyping.Mapping。这些工具只有在需要与3.9之前的Python版本兼容时才应该使用。

202

自从Python 3.5正式发布以来,新增了一个支持类型提示的模块——typing,还有一个相关的List类型,用于通用容器。

换句话说,现在你可以这样做:

from typing import List

def my_func(l: List[int]):
    pass

不过,从Python 3.9开始,这个用法已经不推荐了,现在你可以直接使用内置的list,而不需要再用typing.List

324

截至2015年5月,PEP0484(类型提示)已经正式被接受。相关的草案实现也可以在GitHub上的ambv/typehinting找到。

2015年9月,Python 3.5发布了,支持类型提示,并且新增了一个新的typing模块。这个模块可以用来指定集合中包含的类型。到2015年11月,JetBrains的PyCharm 5.0完全支持Python 3.5,包括类型提示,下面的例子就展示了这一点。

PyCharm 5.0使用类型提示的代码补全

原始回答

截至2014年8月,我确认无法使用Python 3的类型注解来指定集合中的类型(例如:字符串列表)。

使用格式化的文档字符串,比如reStructuredText或Sphinx,是可行的替代方案,并且得到了各种IDE的支持。

看起来Guido正在考虑扩展类型注解的想法,这与mypy的精神相符:http://mail.python.org/pipermail/python-ideas/2014-August/028618.html

撰写回答