typing库
typing 库
引入
在日常代码编写中,由于python语言特性,不用像go等编译性语言一样,在定义函数时就规范参数和放回值的类型。
def demo(a, b):return "a+b"
'''此时 a 和 b 可以传入任意类型参数毫无疑问,这一特性,在定义函数阶段是非常方便的,
毕竟能少写好多东西。但是,在别人调用你写的函数,或者你调用别人写的函数时,
就不那么友好了。因此python推出了 注释功能
'''
def Demo(a: int, b: int) -> int:return a + b

但是,有时候函数接受的参数是列表,里面数据需要全是float类型,这个时候该咋办呢?
因此官方推出了typing库,typing 库是python 提供用来类型标注支持的工具库。可以用来规范开发过程中的规范,可被用于第三方工具,比如类型检查器、集成开发环境、静态检查器等。Python 在运行时并不强制标注函数和变量类型。
备注: typing库于3.5版本引入,本文基于3.8 解释器版本作于记录,在3.10之后 typing包功能更加强大。
typing包最基本的支持由 Any,Union,Tuple,Callable,TypeVar 和 Generic 类型组成。
类型别名
类型别名通过将类型分配给别名来定义
from typing import ListVector = List[float] # Vector 和 List[float] 将被视为可互换的同义词# Vector 类型数据是 列表里面放float类型数据 同 go 中 float类型切片
def scale(scalar: float, vector: Vector) -> Vector:return [scalar * num for num in vector]print(scale.__annotations__) # 查看函数定义的入参和出参类型
# {'scalar': <class 'float'>, 'vector': typing.List[float], 'return': typing.List[float]}
new_vector = scale(2.0, [1.0, -4.2, 5.4])
print(new_vector)
# [2.0, -8.4, 10.8]
类型别名可用于简化复杂类型签名。例如:
from typing import Dict, Tuple, SequenceConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
NewType
可以通过NewType() 辅助函数创建不同的类型
from typing import NewTypeUserId = NewType('UserId', int)
some_id = UserId(524313)def get_user_name(user_id: UserId) -> str:return "%s" % user_iduser_a = get_user_name(some_id)
# 静态类型检查器会将新类型视为它是原始类型的子类。
user_b = get_user_name(22) def user_name(id: int) -> str:return "%s" % iduser_name(some_id)print(type(some_id)) # <class 'int'>print(524313 is some_id) # True

UserId 类型实际上还是 int 类型, 能够支持 int 所有操作.这些检查只是由静态类型检查器来执行,在程序运行时,
UserId = NewType('UserId', int)会产生一个 UserId 函数该函数会立即放回你传递给它的任何参数,不会产生一个新的类,也不会引入超出常规函数调用的额外开销。
# NewType 源码
def NewType(name, tp):def new_type(x):return xnew_type.__name__ = namenew_type.__supertype__ = tpreturn new_type
这同样也意味着,UserId 无法产生子类型。因为实际上并没有这个类
from typing import NewTypeUserId = NewType('UserId', int)
class AdminUserId(UserId): # 执行抛异常pass# TypeError: function() argument 1 must be code, not str
然而,我们可以在 “派生的”
NewType的基础上创建一个NewType
from typing import NewTypeUserId = NewType('UserId', int)ProUserId = NewType('ProUserId', UserId)
Callable
期望特定签名的回调函数的框架可以将类型标注为 Callable[[Arg1Type, Arg2Type], ReturnType]。
Callable 用来检查传入的参数是否是个可调用对象,
[Arg1Type, Arg2Type] :入参
ReturnType : 出参
def feeder(get_next_item: Callable[[], str]) -> None:# Bodyreturn # 等价写法,其实就是将函数作为参数传入, 写装饰器的时候可以用用
def feeder_test(func) -> Callable[[], str]: return func
Sequence
typing 库中的 Sequence 是 collections.abc.Sequence 的泛型版本
collections.abc.Sequence 只读且可变的序列 sequences 的抽象基类。
一种 iterable,它支持通过 __getitem__() 特殊方法来使用整数索引进行高效的元素访问,并定义了一个返回序列长度的 __len__() 方法。内置的序列类型有 list、str、tuple 和 bytes。注意虽然 dict 也支持 __getitem__() 和 __len__(),但它被认为属于映射而非序列,因为它查找时使用任意的 immutable 键而非整数。
collections.abc.Sequence 抽象基类定义了一个更丰富的接口,它在 __getitem__() 和 __len__() 之外又添加了 count(), index(), __contains__() 和 __reversed__()。 实现此扩展接口的类型可以使用 register() 来显式地注册。
泛型(Generic)
泛型,是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。
Python作为一个动态语言,并不会做类型检查,所谓的“类型声明”只是一个“提示(hints)”或者“注解(annotations)”的作用。同理,Python中所谓的泛型也并不会想静态语言那样对输入的参数进行严格的要求,但是可以对类型进行“提示”和“限制”,减少不必要的类型错误。
泛型函数
from typing import TypeVar, List, Union# 通过TypeVar限定为整数型的列表和浮点数的列表
T = TypeVar("T", bound=Union[List[int], List[float]])
# 也可以写成如下形式
T = TypeVar("T", List[int], List[float])def printList(l: T): # printList(l: Sequence[T]):for e in l:print(e)printList([1, 2, 3]) # 打印整数型列表
printList([1.1, 2.2, 3.3]) # 打印浮点数列表
printList(["a", "b", "c"]) # 字符串型列表,出现异常标记
泛型类
from typing import TypeVar, Union, Generic, List# 接受所有类型
T = TypeVar("T")
# 通过TypeVar限定为整数型的列表和浮点数的列表
T = TypeVar("T", bound=Union[int, float])class MyList(Generic[T]):def __init__(self, size: int) -> None:self.size = sizeself.list: List[T] = []def append(self, e: T):self.list.append(e)print(self.list)# 适用于整数型
intList = MyList[int](3) # 通过[int]进行类型提示!
intList.append(101)# 也适用于浮点数
floatList = MyList[float](3)
floatList.append(1.1)# 但不适用于字符串,以下代码通过mypy检查会报错!
strList = MyList[str](3)
strList.append("test")
Generic[T] 作为基类定义了类 LoggedVar 采用单个类型参数 T。这也使得 T 作为类体内的一个类型有效。
Generic 基类定义了 __class_getitem__() ,使得 MyList[t] 作为类型有效:
Generic 每个参数的类型变量必须是不同的。这是无效的:
from typing import TypeVar, Generic
...T = TypeVar('T')class Pair(Generic[T, T]): # 无效...
Generic 支持多重继承:
from typing import TypeVar, Generic, SizedT = TypeVar('T')class LinkedList(Sized, Generic[T]):...# Sized 提供了 __len__() 方法的抽象基类。
# 还有很多 https://docs.python.org/zh-cn/3.8/library/collections.abc.html#
其他参考
相关文章:
typing库
typing 库 引入 在日常代码编写中,由于python语言特性,不用像go等编译性语言一样,在定义函数时就规范参数和放回值的类型。 def demo(a, b):return "ab" 此时 a 和 b 可以传入任意类型参数毫无疑问,这一特性&#…...
linux shell 入门学习笔记10内置shell命令
bash基础的内置命令 echoevalexecexportreadshift echo命令 -n 不换行输出 -e 解析字符串中的特殊符号\n 换行 \r 回车 \t 制表符 四个空格 \b 退格-n参数演示 xiao123xiao123:~/Downloads$ echo 你真胖;echo 你还挺可爱; 你真胖 你还挺可爱 xiao123xiao123:~/Downloads$ ec…...
[动手写操作系统]-02-开机运行系统并打印‘hello‘
文章目录 理解三个概念: 中断interrupts, CPU,寄存器registers 目标:让上一个静默的界面打印一些文本 我们将改进我们的无限循环引导扇区并在屏幕上打印一些东西。我们将为此提出中断。 我们尝试将"Hello"写到寄存器al, 字节0x0e写到ah (the higher part of ax),并…...
Delete `␍`eslint(prettier/prettier) in vscode 的解决方案
错误描述从 Github 仓库拉取代码,使用 vscode 打开,页面报错,每一行都爆红 (如下图)问题原因由于历史原因,windows下和linux下的文本文件的换行符不一致。Windows在换行的时候,使用了换行符CRLF…...
gof23 设计模式 各个模式代码demo
Gof23 设计模式,也叫Gang of Four(GoF)设计模式,是由四位设计模式大师(Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides)撰写的一本书——《设计模式:可复用面向对象软件的基础》所…...
0 初识Kotlin
0 基本介绍 相信很多开发者对Kotlin还是比较陌生的。 Kotlin是一种新型的编程语言,由JetBrains公司开发与设计,在2012年开源, 但没引起什么注意。 直到2017年google宣布将Kotlin作为Android开发的首选语言,Kotlin才开始大放异彩。…...
阿里云服务器部署SpringBoot+Vue项目(宝塔面板傻瓜式操作)
准备工作 一台服务器(我用的是阿里云)SpringBoot项目的jar包Vue项目的dist包 一、购买服务器 然后重置实例密码。 远程连接 登陆成功后安装宝塔面板 二、安装宝塔面板(无账号的注册一个账号) 地址:https://www.bt.cn/new/download.html 选择对应的镜像、不知道…...
27. 移除元素 26. 删除有序数组中的重复项 88. 合并两个有序数组(双指针遍历)
目录[27. 移除元素-力扣](https://leetcode.cn/problems/remove-element/description/?languageTagsc)[26. 删除有序数组中的重复项](https://leetcode.cn/problems/remove-duplicates-from-sorted-array/)[88. 合并两个有序数组](https://leetcode.cn/problems/merge-sorted-…...
什么时候用std::move()?
文章目录1. "是什么?"2. "有何用?"3. "什么时候用?"1. “是什么?” 虽然 std::move() 从技术角度上是一个函数 ,但我认为它不是真正的函数。 它是编译器考虑表达式值的方式之间的转换器。 2. “有何用?” 首先要注意的是 std…...
建立做机器学习项目的范式
建立起做机器学习项目的范式,萃取出核心步骤,避免后面做项目没有明确的方向。 核心步骤: 1、明确自己想做什么样的项目,感兴趣的领域; 2、找到满足项目的数据集,开源的或者自建数据集; 数据…...
搭建k8s高可用集群—20230225
文章目录多master(高可用)介绍高可用集群使用技术介绍搭建高可用k8s集群步骤1. 准备环境-系统初始化2. 在所有master节点上部署keepalived3.1 安装相关包3.2 配置master节点3.3 部署haproxy错误解决3. 所有节点安装Docker/kubeadm/kubelet4. 部署Kuberne…...
Java 修饰符和多态
文章目录一、修饰符1. 权限修饰符2. 状态修饰符2.1 final2.2 static二、多态1. 成员访问特点2. 多态中的转型3. 多态案例一、修饰符 1. 权限修饰符 2. 状态修饰符 2.1 final final 关键字是最终的意思,可以修饰成员方法、成员变量及类。 //1.修饰成员变量 publi…...
学了一年Java的我,想转嵌入式了
秋名山码民的主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 🙏作者水平有限,如发现错误,还请私信或者评论区留言! 目录前言为啥我想去转行?如果我现在选择转硬件,我…...
【Git】Git冲突与解决方法
目录 一、Git冲突如何产生? 二、解决Git冲突—手动修改冲突 【第一步】在 hot-fix 分支上增加如下代码,并且提交。 【第二步】在master 分支上同样的地方增加如下代码,并且提交。 【第三步】 我们现在在 master 分支上合并 hot-fix 分支&a…...
深度剖析数据在内存的存储
目录1.深度剖析数据在内存的存储(前言)数据类型介绍类型的基本归类整形在内存中的存储原码、反码、补码大小端练习总结1.深度剖析数据在内存的存储(前言) 今天就让我戴佳伟给大家讲一下数据在内存中的存储。之中有好多让我们深思的点,大家都拿起笔记本,…...
身高排序(绝对值大的排后面,小的排前面)
题目描述 小明今年升学到了小学一年级,来到新班级后,发现其他小朋友身高参差不齐,然后就想基于各小朋友和自己的身高差,对他们进行排序,请帮他实现排序 输入描述 第一行为正整数H和N 0 < H < 200 为小明的身高…...
高频前端面试题之HTML篇(三)
11. label的作用是什么?是怎么用的? label元素不会向用户呈现任何特殊效果,但是,它为鼠标用户改进了可用性,当我们在label元素内点击文本时就会触发此控件。也就是说,当用户选择该标签时,浏览器…...
使用DG备份恢复测试库的流程以及可能出现的问题
使用DG备份恢复测试库的流程以及可能出现的问题 评估数据量和服务器存储空间从DG备库备份全库和归档日志清理测试库环境测试库恢复备份(一)从DG主库备份控制文件测试库恢复备份(二)从DG备库备份最新的归档日志测试库恢复备份(三)需要单独备份数据文件的情况思路:从DG备库…...
Springboot注释解析
SpringBootApplication 标注主程序类 说明一个spring boot应用 SpringBootConfiguration 标注为spring boot配置类 EnableAutoConfiguration 开启自动配置功能 AutoConfigurationPackage 自动配置包 Import({Registrar.class}) 导入一个容器到组件 Registrar.class…...
C语言之通讯录(动态 存储文件版)
目录 前言 一.基本思路 二.代码的实现 2.1通讯录菜单 2.2通讯录的定义及功能 2.3函数实现 2.3.1初始化通讯录 2.3.2文件信息传递到通讯录里 2.3.3扩容通讯录 2.3.4增加联系人 2.3.5删除联系人 2.3.6查询联系人 2.3.7修改联系人 2.3.8打印通讯录 2.3.9信息保留在文…...
Awoo Installer深度解析:破解Switch游戏安装困境的全能工具
Awoo Installer深度解析:破解Switch游戏安装困境的全能工具 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 在Nintendo Switch破解社区…...
丹青幻境功能全解析:宣纸UI、动态LoRA、文艺交互实操
丹青幻境功能全解析:宣纸UI、动态LoRA、文艺交互实操 1. 数字艺术创作新范式 在数字艺术创作领域,丹青幻境Z-Image Atelier带来了一场界面革命。这款工具将4090显卡的强大算力隐藏在仿古宣纸界面背后,为创作者提供了前所未有的沉浸式体验。…...
TL494电源芯片避坑指南:常见设计误区与调试技巧
TL494电源芯片避坑指南:常见设计误区与调试技巧 在电源设计领域,TL494作为一款经典PWM控制芯片,凭借其稳定性和灵活性赢得了工程师的青睐。但就像任何工具一样,只有真正理解它的特性才能发挥最大价值。本文将带您深入TL494的设计细…...
Qt跨平台即时通讯实战:从界面设计到TCP通信的完整实现
1. Qt跨平台即时通讯开发概述 用Qt框架开发即时通讯软件最大的优势就是"一次编写,到处运行"。我去年接手过一个项目,需要在Windows和Linux双平台上部署聊天工具,当时尝试过多种技术方案,最终Qt以绝对优势胜出。想象一下…...
**发散创新:基于微应用架构的轻量级权限控制实战设计**在现代前端开
发散创新:基于微应用架构的轻量级权限控制实战设计 在现代前端开发中,**微应用(Micro Frontend)*8 已成为构建复杂单页应用(SPA)的标准方案之一。它允许团队独立开发、部署和维护各自的功能模块,…...
快手数据采集引擎:无水印解析与多源内容整合工具
快手数据采集引擎:无水印解析与多源内容整合工具 【免费下载链接】kuaishou-crawler As you can see, a kuaishou crawler 项目地址: https://gitcode.com/gh_mirrors/ku/kuaishou-crawler 价值定位:重新定义短视频数据采集标准 在数字内容分析与…...
告别模糊边界!用Monodepth2实战KITTI深度估计,详解自动掩码与最小重投影损失
告别模糊边界!用Monodepth2实战KITTI深度估计,详解自动掩码与最小重投影损失 深度估计是计算机视觉领域的一项基础任务,它试图从2D图像中恢复出3D场景的几何信息。在自动驾驶、机器人导航、增强现实等应用中,准确的深度感知至关重…...
Agent如何帮助企业实现人效最大化?——深度拆解AI Agent驱动的企业生产力变革路径
在2026年的产业化浪潮中,AI Agent正在从“技术概念”转变为企业实现“人效最大化”的核心驱动力。这场变革的本质并非简单的工具迭代,而是企业组织形态与工作流的深度重塑。通过将人类从重复、低效的执行性工作中解放出来,企业智能自动化正推…...
Cadence Virtuoso实战:从反相器原理图到GDS版图,手把手搞定你的第一个CMOS Layout
Cadence Virtuoso实战:从反相器原理图到GDS版图全流程解析 在集成电路设计领域,从原理图到物理版图的实现是一个充满挑战又极具成就感的过程。对于初入行的工程师或微电子专业学生来说,掌握Cadence Virtuoso工具链的完整工作流程,…...
DeerFlow免费开源:字节跳动出品,个人研究者的强大AI工具
DeerFlow免费开源:字节跳动出品,个人研究者的强大AI工具 1. 项目概述 DeerFlow是由字节跳动公司开源的一款深度研究辅助工具,基于LangStack技术框架开发。这个项目通过整合语言模型、网络搜索和Python代码执行等能力,为个人研究…...
