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信息保留在文…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
