Python是一门动态语言,变量和函数的参数不区分类型,好处是方便,灵活。坏处是别人不能直观的看到数据的类型,IDE也不能给出类型提示。
python解释器不会因为类型标注而有其他额外的类型校验,检查等。只是方便人看和IDE进行提示,语法检查等工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响。
python3.5之后的版本才支持,3.5版本并不支持。
用变量名: 类型名
指定函数的参数类型,用-> 类型名
指定函数的返回值类型
# 变量注解
num: int = 100
# 参数注解
def greeting(name: str) -> str:
return 'Hello ' + name
class Person:
def __init__(self):
self.Name: str = "August Rush"
self.Age: int = 18
就是一些built-in的类型,如int
, float
, complex
, bool
, str
, None
, list
, tuple
, set
, dict
,不过后面四个作为注解太弱势了,我们只知道变量是什么类型,但是它的元素类型是啥我们无法得知,这时候我们就需要借助typing
模块
List,列表,是list
的泛型,基本等同于 list,其后紧跟一个方括号,里面代表了构成这个列表的元素类型
from typing import List
name: List[str] = [3, "亚索", "瑞雯", "菲奥娜"]
另外还可以嵌套声明都是可以的:
lists: List[List[int]] = [[1, 2], [2, 3]]
Tuple,元组,是tuple
的泛型,其后紧跟一个方括号,方括号中按照顺序声明了构成本元组的元素类型,如 Tuple[X, Y] 代表了构成元组的第一个元素是 X 类型,第二个元素是 Y 类型
from typing import Tuple
info: Tuple[str, int, float] = ("樱木花道", 18, 183.0)
同样地也可以像List一样使用类型嵌套
tuples: Tuple[Tuple[int]] = ((1, 2), (3, 4))
Dict,字典,是dict
的泛型;Mapping,映射,是collections.abc.Mapping
的泛型。根据官方文档,Dict 推荐用于注解返回类型,Mapping 推荐用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,中括号内分别声明键名、键值的类型
from typing import Dict, Mapping
d: Dict[str, int] = {"1": 1, "2": 2}
m: Mapping[str, int] = {"1": 1, "2": 2}
Set,集合,是set
的泛型;AbstractSet,是collections.abc.Set
的泛型。根据官方文档,Set 推荐用于注解返回类型,AbstractSet 用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,里面声明集合中元素的类型
from typing import Set, AbstractSet
num: Set[int] = {1, 2, 3}
flag: AbstractSet[bool] = {True, False}
Sequence,是collections.abc.Sequence
的泛型,在某些情况下,我们可能并不需要严格区分一个变量或参数到底是列表 list 类型还是元组tuple 类型,我们可以使用一个更为泛化的类型,叫做 Sequence,其用法类似于 List
from typing import Sequence
msgs: Sequence[str] = ["我", "爱", "你"]
NoReturn,当一个方法没有返回结果时,为了注解它的返回类型,我们可以将其注解为 NoReturn
from typing import NoReturn
def show() -> NoReturn:
print("test NoReturn")
Any,是一种特殊的类型,它可以代表所有类型,静态类型检查器的所有类型都与 Any 类型兼容,所有的无参数类型注解和返回类型注解的都会默认使用 Any 类型,也就是说,下面两个方法的声明是完全等价的:
from typing import Any
def add(a):
return a + 1
def add(a: Any) -> Any:
return a + 1
Callable,可调用类型,它通常用来注解一个方法,Callable 在声明的时候需要使用Callable[[Arg1Type, Arg2Type, ...], ReturnType]
这样的类型注解,将参数类型和返回值类型都要注解出来
from typing import Callable, NoReturn
def show(msg: str) -> NoReturn:
print(msg)
def get_msg(msg: str, func: Callable[[str], NoReturn]) -> NoReturn:
func(msg)
Union,联合类型,Union[X, Y]
代表要么是 X 类型,要么是 Y 类型
Optional,意思是说这个参数可以为空或已经声明的类型,即Optional[X]
等价于Union[X, None]
,注意,只能是一个类型,Optional[X, Y]是错的,但值得注意的是,这个并不等价于可选参数,当它作为参数类型注解的时候,不代表这个参数可以不传递了,而是说这个参数可以传为 None
如果想代表一个生成器类型,可以使用 Generator,它的声明比较特殊,其后的中括号紧跟着三个参数,分别代表YieldType
、SendType
、ReturnType
from typing import Generator
def echo_round() -> Generator[int, float, str]:
sent = yield 0
while sent >= 0:
sent = yield round(sent)
return 'Done'
当然很多情况下,生成器往往只需要yield
内容就够了,我们是不需要 SendType 和 ReturnType 的,可以将其设置为空Generator[int, None, None]
这个实际上指的就是可迭代类型和迭代器类型,后面中括号内的是迭代的元素的类型
from typing import Iterable, Iterator
def func(a: Iterator[int], b: Iterable[float]):
print(a, b)
直接上示例,其实就是把定义好的类型注解取个名字
from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
TypeVar,我们可以借助它来自定义兼容特定类型的变量,比如有的变量声明为 int、float、None 都是符合要求的,实际就是代表任意的数字或者空内容都可以,其他的类型则不可以,比如列表 list、字典 dict 等等,像这样的情况,我们可以使用 TypeVar 来表示 例如一个人的身高,便可以使用 int 或 float 或 None 来表示,但不能用 dict 来表示,所以可以这么声明:
from typing import TypeVar
height = 1.75
Height = TypeVar('Height', int, float, None)
def get_height() -> Height:
return height
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建