It should also be emphasized that*Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.* Guido van Rossum, Jukka Lehtosalo, and Łukasz Langa, PEP 484—Type Hints
这一用法被称为 type hints,即类型提示。使用方法主要是在变量后添加冒号并指定其类型,例如“a: int”。除此之外,type hints 也可以用于指定函数的返回值类型,这需要在函数定义的第一行(即 def 行)最后添加箭头符号,并指定返回值类型,例如“... -> dict”。
def two_sum(nums: list, target: int) -> list:
dct = {} # 这里不必显式标注dct: dict = {},
# 因为编辑器可以通过类型推断自动推导出dct的类型为dict
for i, num in enumerate(nums):
if dct.get(target - num) is not None:
return [i, dct.get(target - num)]
dct[num] = i
def two_sum(nums: list[int], target: int) -> list[int]:
dct: dict[int, int] = {} # 也可以这样具体地标注dct的类型
for i, num in enumerate(nums):
if dct.get(target - num) is not None:
return [i, dct.get(target - num)]
dct[num] = i
from typing import List, Dict
def two_sum(nums: List[int], target: int) -> List[int]:
dct: Dict[int, int] = {} # 也可以这样具体地标注dct的类型
for i, num in enumerate(nums):
if dct.get(target - num) is not None:
return [i, dct.get(target - num)]
dct[num] = i
也可以用“Any”表示任意类型。不过不建议这么做,因为把类型标成 Any 等于什么都没标,意义不大。下面是用“Any”实现的 reduce 函数,但实际上应该使用泛型,不过这里不再过多赘述泛型的语法,感兴趣可以自己查。
from typing import Callable, Iterable, Optional, Any
ReduceFunc = Callable[[Any, Any], Any]
def reduce(func: ReduceFunc, args: Iterable[Any], start_value: Optional[Any] = None) -> Any:
if start_value is None:
# 若不提供起始值,将第一个参数作为起始值
total = args[0]
for arg in args[1:]:
total = func(total, arg)
else:
total = start_value
for arg in args[1:]:
total = func(total, arg)
return total
reduce(lambda total, x: str(total) + ", " + str(x), [1, 2, 3, 4, 5]) # => '1, 2, 3, 4, 5'
# 泛型版本的reduce,不提供解释,感兴趣自己查
from typing import TypeVar
T = TypeVar("T")
def reduce(func: Callable[[T, T], T], args: Iterable[T], start_value: Optional[T] = None) -> T:
if start_value is None:
total = args[0]
for arg in args[1:]:
total = func(total, arg)
else:
total = start_value
for arg in args[1:]:
total = func(total, arg)
return total
有时候我们也可能只想限定某个参数只能是特定值之一。接触过其他语言者可能会考虑使用枚举类型,在 Python 3.4 中同样对枚举类型(Enum)添加了支持,但使用 type hints 可以更优雅地解决这一问题:
from typing import Literal
# Literal即字面量,不了解这个概念的可以很轻松地从网上找到这一名词的解释
# 这里表示新建一个类型Fruit,且只能是Literal[]中的三个类型之一
Fruit = Literal['apple', 'pear', 'banana']
def sell(fruit: Fruit):
...
此外,Python 的 type hints 还对泛型、鸭子类型(结构化类型)、自引用等高级特性提供了支持,在这里不再过多赘述。
尽管对于一些程序员来说,type hints 可能并不是特别常用,但使用 type hints 确实是一个很好的习惯,在一些大型公司中为了编写易于维护 Python 项目而大量使用 type hints 也是很常见的。如果你非要在转专业考试中使用 type hints,自然也没人拦着你,但你需要了解到转专业使用的 Python 版本是 3.8,有一些最新的特性无法使用。我也不建议在考试时使用 type hints,因为写点小程序没必要用 type hints,写大型项目用这个才有意义。