Python does not have variables, like other languages where variables have a type and a value; it has names pointing to objects, which know their type.
然而,自2010年(首次提出这个问题时)以来,有一件有趣的事情发生了变化,那就是PEP 3107(在Python 3中实现)的实现。现在您可以实际指定参数的类型和函数的返回类型,如下所示:def pick(l: list, index: int) -> int:
return l[index]
我们可以看到pick有两个参数,一个列表l和一个整数index。它还应该返回一个整数。
因此这里暗示l是一个整数列表,我们可以不费吹灰之力就看到它,但是对于更复杂的函数,它可能会有点混淆列表应该包含什么。我们还希望index的默认值为0。要解决这个问题,您可以选择这样写pick:def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
请注意,我们现在将字符串作为l类型放入,这在语法上是允许的,但对于以编程方式进行解析(稍后我们将讨论)。
需要注意的是,Python不会引发一个TypeError如果你将一个float传递给index,这是Python设计理念的一个要点:“我们都是这里的同意成年人”,这意味着你应该知道什么可以传递给函数,什么不能传递给函数。如果你真的想编写代码这会抛出类型错误,您可以使用isinstance函数检查传递的参数是否属于正确的类型或其子类,如下所示:def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
在下一节和评论中,我们将详细讨论为什么很少这样做,以及应该做什么。
PEP 3107不仅提高了代码的可读性,而且还提供了几个适合您阅读的关于here的用例。
随着PEP 484的引入,类型注释在Python 3.5中得到了更多的关注,它引入了一个用于类型提示的标准模块。
这些类型提示来自类型检查器mypy(GitHub),它现在是PEP 484兼容的。
输入模块附带了相当全面的类型提示集合,包括:List,Tuple,Set,Map-分别用于list,tuple,set和map。
Iterable-对生成器有用。
Any-当它可以是任何东西的时候。
Union-当它可以是指定类型集中的任何内容时,而不是Any。
Optional-当它可能为None时。Union[T, None]的简写。
TypeVar-与泛型一起使用。
Callable-主要用于函数,但也可以用于其他可调用函数。
下面是使用输入模块中介绍的注释方法的旧示例:from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
一个强大的特性是Callable,它允许您键入以函数作为参数的注释方法。例如:from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
使用TypeVar,而不是Any,上面的例子可能会更精确,但这是留给读者的练习,因为我相信我的答案中已经包含了太多关于通过类型提示启用的奇妙新功能的信息。
以前,当一个文档化的Python代码(例如Sphinx)可以通过编写如下格式的docstring来获得上述一些功能时:def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
如您所见,这需要很多额外的行(确切的行数取决于您想要的显式程度以及您如何格式化docstring)。但现在您应该清楚了PEP 3107如何提供一个在许多(all?)中的替代方案太好了。尤其是与PEP 484结合使用时,正如我们所看到的,它提供了一个标准模块,该模块定义了这些类型提示/注释的语法,这些类型提示/注释可以以una模棱两可,精确而灵活,形成强大的组合。
在我个人看来,这是Python有史以来最棒的特性之一。我等不及人们开始利用它的力量了。很抱歉回答得太长了,但当我兴奋的时候就会这样。
大量使用类型暗示的Python代码示例可以找到here。