Python 静态类型检查 mypy 示例
以下所有例子都参考了最新版本的 Python 文档与 mypy 文档
必备条件
安装最新版本的 Python 和 mypy
要学会按需配置自己的编辑器,比如我的 VSCode 就装好了 Python 和 Pyright 扩展
变量
age: int = 1
child: bool
if age < 18:
child = True
else:
child = False
常量
from typing import Final
RATE: Final = 3000
class Base:
DEFAULT_ID: Final = 0
RATE = 300 # Error: can't assign to final attribute
Base.DEFAULT_ID = 1 # Error: can't override a final attribute
内置类型
from typing import List, Set, Dict, Tuple, Optional
x: int = 1
x: float = 1.0
x: bool = True
x: str = "test"
x: bytes = b"test"
# 集合类型是首字母大写的
# 元素的类型写在中括号里面(泛型)
x: List[int] = [1]
x: Set[int] = {6, 7}
# 字典需要写出 key 和 value 的类型
x: Dict[str, float] = {"field": 2.0}
# 元组需要写出所有元素的类型
x: Tuple[int, str, float] = (3, "yes", 7.5)
# 用 Optional[] 表示可以为 None 的类型
x: Optional[str] = some_function()
# mypy 可以推断出 if 语句里 x 不能为 None
if x is not None:
print(x.upper())
# 如果 x 的值不可能为 None, 用 assert
assert x is not None
print(x.upper())
函数
from typing import Callable, Iterator, Union, Optional, List
def stringify(num: int) -> str:
return str(num)
def plus(num1: int, num2: int) -> int:
return num1 + num2
def f(num1: int, my_float: float = 3.5) -> float:
return num1 + my_float
# callable (函数) 类型
x: Callable[[int, float], float] = f
# 生成器函数会返回可迭代的元素
def g(n: int) -> Iterator[int]:
i = 0
while i < n:
yield i
i += 1
类
from typing import ClassVar
class MyClass:
attr: int
# 实例变量可以有默认值
charge_percent: int = 100
# 什么也不返回,就是返回 None
def __init__(self) -> None:
...
# 实例方法,省略 self 的类型
def my_method(self, num: int, str1: str) -> str:
return num * str1
# 类可以用作类型
x: MyClass = MyClass()
# 类变量
class Car:
seats: ClassVar[int] = 4
passengers: ClassVar[List[str]]
# 需要注意还没定义就使用一个类会报错
def f(foo: A) -> int: # Error
...
class A:
...
# 你可以使用字符串的形式来规避
def f(foo: "A") -> int: # OK
...
Named tuples 命名元组
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
p = Point(x=1, y="x") # Error: Argument has incompatible type "str"; expected "int"
异步迭代器
from typing import AsyncIterator
async def gen() -> AsyncIterator[bytes]:
lst = [b async for b in gen()] # 推断类型是 "List[bytes]"
yield "no way" # Error: Incompatible types (got "str", expected "bytes")
类型别名
AliasType = Union[List[Dict[Tuple[int, str], Set[int]]], Tuple[str, List[str]]]
def f() -> AliasType:
...
Dataclasses 数据类
from dataclasses import dataclass, field
@dataclass
class Application:
name: str
plugins: List[str] = field(default_factory=list)
test = Application("Testing...") # OK
bad = Application("Testing...", "with plugin") # Error: List[str] expected
泛型
from typing import TypeVar, Generic
T = TypeVar("T")
class Stack(Generic[T]): # 泛型
def __init__(self) -> None:
self.items: List[T] = []
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
return self.items.pop()
def empty(self) -> bool:
return not self.items
# Stack[int] 实例
stack = Stack[int]()
stack.push(2)
stack.pop()
stack.push("x") # Type error
Literal types
PrimaryColors = Literal["red", "blue", "yellow"]
SecondaryColors = Literal["purple", "green", "orange"]
AllowedColors = Literal[PrimaryColors, SecondaryColors]
def paint(color: AllowedColors) -> None: ...
paint("red") # OK
paint("turquoise") # Error
Protocol 协议
实现结构化子类型(静态鸭子类型),可以当成接口一样用。
from typing import Iterable, Protocol
class SupportsClose(Protocol):
def close(self) -> None:
... # 函数体可以为空 (explicit '...')
class Resource: # 没有写 SupportsClose
def close(self) -> None:
self.resource.release()
def close_all(items: Iterable[SupportsClose]) -> None:
for item in items:
item.close()
close_all([Resource(), open("some/file")]) # OK
Abstractmethod 抽象方法
方法可以有默认的实现,但是抽象方法规定必须在子类中实现。
from typing import Protocol
from abc import abstractmethod
class Example(Protocol):
def first(self) -> int:
return 42
@abstractmethod
def second(self) -> int: # 没有默认实现
raise NotImplementedError # 防止这个方法被调用
Enum 枚举
如果要像 C 语言一样定义枚举的话,也是用类来实现的。
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED)
这样就能用类当成枚举一样用了。
参考资料
- mypy 官方文档
- PEP 484 type hints including generics
- PEP 526 syntax for variable annotations
- PEP 544 structural subtyping
- PEP 589 typed dictionaries
Python 静态类型检查 mypy 示例的更多相关文章
- Java中静态类型检查是如何进行的
以下内容来自维基百科,关于静态类型检查和动态类型检查的解释: 静态类型检查:基于程序的源代码来验证类型安全的过程: 动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间 ...
- Python静态代码检查工具Flake8
简介 Flake8 是由Python官方发布的一款辅助检测Python代码是否规范的工具,相对于目前热度比较高的Pylint来说,Flake8检查规则灵活,支持集成额外插件,扩展性强.Flake8是对 ...
- 理解Flow静态类型检查
一.为什么在JavaScript中使用静态类型 了解静态类型的最快方法是将其与动态类型进行对比. 有静态类型参数的语言被称为静态类型语言. 另一方面,有动态类型参数的语言被称为动态类型语言.核心区别是 ...
- 编译器开发系列--Ocelot语言6.静态类型检查
关于"静态类型检查",想必使用C 或Java 的各位应该非常熟悉了.在此过程中将检查表达式的类型,发现类型不正确的操作时就会报错.例如结构体之间无法用+ 进行加法运算,指针和数值之 ...
- Flow: JavaScript静态类型检查工具
Flow: JavaScript静态类型检查工具 Flow是Facebook出品的,针对JavaScript的静态类型检查工具.其代码托管在github之上,并遵守BSD开源协议. 关于Flow 它可 ...
- flow 静态类型检查 js
1.flow介绍 https://ustbhuangyi.github.io/vue-analysis/prepare/flow.html#为什么用-flow 2.使用 (1)安装flow (2)项目 ...
- 如何使用flow进行静态类型检查
Flow 是 facebook 出品的 JavaScript 静态类型检查⼯具.Vue.js 的源码利⽤了 Flow 做了静态类型检查,所以了解 Flow 有助于我们阅读源码. 为什么⽤ Flow? ...
- Python 加入类型检查
Python 是一门强类型的动态语言, 对于一个 Python 函数或者方法, 无需声明形参及返回值的数据类型, 在程序的执行的过程中, Python 解释器也不会对输入参数做任何的类型检查, 如果程 ...
- flow JavaScript 静态类型检查工具
内置类型 flow 内置类型有 boolean, number, string, null, void, any, mixed, literal type. 其中 boolean, number, s ...
随机推荐
- Docker基础内容之镜像构建
前言 Docker可以通过读取Dockerfile中的指令来自动构建图像.Dockerfile是一个文本文档,包含用户可以在命令行上调用的所有命令来组装一个图像.使用docker构建用户可以创建一个自 ...
- 理解Java虚拟机中的栈、堆、堆栈
JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 栈区: 每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不 ...
- SVM(1)模式识别课堂笔记
引言:当两类样本线性可分时,针对我们之前学习的感知机而言,存在多个超平面能将数据分开,这里要讨论什么样的分类面最好的问题.为此,我们形式化的定义了最优分类超平面,他有两点特征:1.能将训练样本没有错误 ...
- 异常处理 | manual close is not allowed over a Spring managed SqlSession
背景: 今天启动一个老项目,控制台打印出以下异常,大概是说在Spring托管的SqlSession上不允许手动关闭: java.lang.UnsupportedOperationException: ...
- node + multer存储element-ui上传的图片
说明 element-ui的Upload组件可以帮助我们上传我们的图片到我们的服务器,可以使用action参数上传图片,也可以使用http-request自定义上传方式.这里我们使用自定义的方式上传. ...
- es学习(三):分词器介绍以及中文分词器ik的安装与使用
什么是分词 把文本转换为一个个的单词,分词称之为analysis.es默认只对英文语句做分词,中文不支持,每个中文字都会被拆分为独立的个体. 示例 POST http://192.168.247.8: ...
- JS刷算法题:二叉树
Q1.翻转二叉树(easy) 如题所示 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 来源:力扣(LeetCode) ...
- .NET异步编程之APM模式
目录 1.AMP模式简介 2.使用BeginInvoke实现异步委托 3.原始线程怎么知道新线程已经运行完毕 4.使用AsyncCallback委托实现回调模式 5.源代码下载 shanzm-2020 ...
- supervisor管理tomcat
操作目的:用supervisor工具管理tomcat服务 配置环境,安装服务,以及多实例 脚本编辑: 前提 机器的opt目录下必须有jdk-8u131-linux-x64_.rpm 以及apache- ...
- Visual Studio 2015 配置 Python 环境
Visual Studio 2015可以在安装时选择安装Python环境,首次使用VS2015执行python时需要配置环境变量: 配置VS2015的环境前需要先下载Python并安装: https: ...