type annotation / static checker / dynamic checker of python
type annotations
https://docs.python.org/3.6/library/typing.html
为类类型提示(IDE or 人类可读)设计, 又叫类型注解。
typing
— Support for type hintsThis module supports type hints as specified by PEP 484 and PEP 526. The most fundamental support consists of the types
Any
,Union
,Tuple
,Callable
,TypeVar
, andGeneric
. For full specification please see PEP 484. For a simplified introduction to type hints see PEP 483.def greeting(name: str) -> str: return 'Hello ' + nameIn the function
greeting
, the argumentname
is expected to be of typestr
and the return typestr
. Subtypes are accepted as arguments.
内置类型
https://zhuanlan.zhihu.com/p/387535490
内置类型:
类型 描述 int 整数 float 浮点数 bool 布尔值 str 字符串 bytes 8-bit 字符串 object 对象 Any 任意类型 list[str] 字符串数组 tuple[int, int] 2个整数元素的元祖 tuple[int, ...] 任意数量整数元素的元祖 dict[str, int] key为字符串,value是整数的字典 Iterable[int] 可迭代类型,元素为整数 Sequence[bool] 布尔值序列 Mapping[str, int] key是字符串,value是整数的映射
还有其他 callable class等复杂类型。
与类型检查无关
但是不会影响到运行时的行为, 不会对运行时变量的类型做检查。
https://zhuanlan.zhihu.com/p/37239021
然后特别要强调的是,Python 解释器并不会因为这些注解而提供额外的校验,没有任何的类型检查工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响:
输出:
但这么做的好处是:
- 让别的程序员看得更明白
- 让 IDE 了解类型,从而提供更准确的代码提示、补全和语法检查(包括类型检查,可以看到 str 和 float 类型的参数被高亮提示)
在函数的
__annotations__
属性中会有你设定的注解:
输出:
静态类型检查
https://www.zhihu.com/question/28764803
不运行程序, 仅仅从词法 语法 语义角度去分析代码, 查找代码缺陷, 其中包括 变量类型 匹配检查。
根据维基百科,静态代码检查又称为静态程序分析,是指在不运行计算机程序的条件下,进行程序分析的方法。静态代码检查工具会从词法、语法、语义等多维度去对工程代码扫描分析,发现可能存在的问题,比如变量未定义、类型不匹配、变量作用域问题、数组下标越界、内存泄露等问题。工具会按照自己的规则进行问题的严重等级划分,给出不同的标识和提示。
mypy -- python static checker
https://github.com/python/mypy
python代码添加类型注解后, 使用mypy来做静态分析。
动态类型代码(无类型注解) 和 静态类型代码(有类型注解) 可以混用。
Mypy is an optional static type checker for Python. You can add type hints (PEP 484) to your Python programs, and use mypy to type check them statically. Find bugs in your programs without even running them!
You can mix dynamic and static typing in your programs. You can always fall back to dynamic typing when static typing is not convenient, such as for legacy code.
例子
https://zhuanlan.zhihu.com/p/141504225#
# headlines.py def headline(text: str, align: bool = True) -> str: if align: return f"{text.title()}\n{'-' * len(text)}" else: return f" {text.title()} ".center(50, "o") print(headline("python type checking")) print(headline("use mypy", align="center"))
$ mypy headlines.py headlines.py:10: error: Argument "align" to "headline" has incompatible type "str"; expected "bool"
Reference
https://mypy.readthedocs.io/en/stable/index.html
类型动态检查
https://github.com/samuelcolvin/pydantic
复用 typing 类型, 定义 数据模型, 对输入数据进行类型校验。
Data validation and settings management using Python type hinting.
Fast and extensible, pydantic plays nicely with your linters/IDE/brain. Define how data should be in pure, canonical Python 3.6+; validate it with pydantic.
from datetime import datetime from typing import List, Optional from pydantic import BaseModel class User(BaseModel): id: int name = 'John Doe' signup_ts: Optional[datetime] = None friends: List[int] = [] external_data = {'id': '123', 'signup_ts': '2017-06-01 12:22', 'friends': [1, '2', b'3']} user = User(**external_data) print(user) #> User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] print(user.id) #> 123