typing库

news2024/11/19 7:46:31

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包最基本的支持由 AnyUnionTupleCallableTypeVarGeneric 类型组成。

类型别名

类型别名通过将类型分配给别名来定义

from typing import List

Vector = 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, Sequence

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

NewType

可以通过NewType() 辅助函数创建不同的类型

from typing import NewType

UserId = NewType('UserId', int)
some_id = UserId(524313)

def get_user_name(user_id: UserId) -> str:
    return "%s" % user_id


user_a = get_user_name(some_id)
# 静态类型检查器会将新类型视为它是原始类型的子类。
user_b = get_user_name(22)  

def user_name(id: int) -> str:
    return "%s" % id

user_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 x
    new_type.__name__ = name
    new_type.__supertype__ = tp
    return new_type

这同样也意味着,UserId 无法产生子类型。因为实际上并没有这个类

from typing import NewType

UserId = NewType('UserId', int)
class AdminUserId(UserId):   # 执行抛异常
    pass

# TypeError: function() argument 1 must be code, not str

然而,我们可以在 “派生的” NewType 的基础上创建一个 NewType

from typing import NewType

UserId = NewType('UserId', int)

ProUserId = NewType('ProUserId', UserId)

Callable

期望特定签名的回调函数的框架可以将类型标注为 Callable[[Arg1Type, Arg2Type], ReturnType]

Callable 用来检查传入的参数是否是个可调用对象,

[Arg1Type, Arg2Type] :入参

ReturnType : 出参

def feeder(get_next_item: Callable[[], str]) -> None:
    # Body
    return 

# 等价写法,其实就是将函数作为参数传入, 写装饰器的时候可以用用
def	feeder_test(func) -> Callable[[], str]: 
    return func


Sequence

typing 库中的 Sequence 是 collections.abc.Sequence 的泛型版本

collections.abc.Sequence 只读且可变的序列 sequences 的抽象基类。

一种 iterable,它支持通过 __getitem__() 特殊方法来使用整数索引进行高效的元素访问,并定义了一个返回序列长度的 __len__() 方法。内置的序列类型有 liststrtuplebytes。注意虽然 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 = size
        self.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, Sized

T = TypeVar('T')

class LinkedList(Sized, Generic[T]):
    ...
    
# Sized  提供了 __len__() 方法的抽象基类。 
# 还有很多 https://docs.python.org/zh-cn/3.8/library/collections.abc.html#

其他参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/371425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

漏洞分析: WSO2 API Manager 任意文件上传、远程代码执行漏洞

漏洞描述 某些WSO2产品允许不受限制地上传文件&#xff0c;从而执行远程代码。以WSO2 API Manager 为例&#xff0c;它是一个完全开源的 API 管理平台。它支持API设计&#xff0c;API发布&#xff0c;生命周期管理&#xff0c;应用程序开发&#xff0c;API安全性&#xff0c;速…

【RockerMQ】001-RockerMQ 概述

【RockerMQ】001-RockerMQ 概述 文章目录【RockerMQ】001-RockerMQ 概述一、MQ 概述1、MQ 简介2、MQ 用途限流削峰异步解耦数据收集3、常见 MQ 产品概述对比4、MQ 常见协议二、RocketMQ 概述1、简介2、发展历史一、MQ 概述 1、MQ 简介 MQ&#xff0c;Message Queue&#xff0…

C++设计模式(22)——状态模式

亦称&#xff1a; State 意图 状态模式是一种行为设计模式&#xff0c; 让你能在一个对象的内部状态变化时改变其行为&#xff0c; 使其看上去就像改变了自身所属的类一样。 问题 状态模式与有限状态机 的概念紧密相关。 有限状态机。 其主要思想是程序在任意时刻仅可处…

【数据库】数据库的完整性

第五章 数据库完整性 数据库完整性 数据库的完整性是指数据的正确性和相容性 数据的正确性是指数据是符合现实世界语义&#xff0c;反映当前实际状况的数据的相容性是指数据库的同一对象在不同的关系中的数据是符合逻辑的 关系模型中有三类完整性约束&#xff1a;实体完整性…

中创公益|中创算力荣获“2022年度突出贡献爱心企业”

公益是什么&#xff1f;不啻微芒造炬成阳萤火虽微愿为其芒公益是持之以恒的努力&#xff0c;中创于2021年1月成立&#xff0c;同年4月中创就开始了公益活动&#xff0c;并对尖山村贫困儿童进行定期捐助。截至2023年&#xff0c;中创先后7次来到被捐助的贫困儿童家中&#xff0c…

【Git】IDEA整合Git详细步骤 — IDEA如何配置Git忽略文件

目录 一、IDEA整合Git 定位 Git 程序 —》IDEA配置Git程序 初始化本地库—》在idea中初始化项目&#xff0c;将项目纳入git管理 添加到暂存区 提交到本地库 方法一: 右键点击项目---> Git ----> Commit Directory 方法二: 点击绿色图标 √ 切换版本 创建分支 切换分…

chatgpt的原理 第一部分

前言 这两天&#xff0c;ChatGPT模型真可谓称得上是狂拽酷炫D炸天的存在了。一度登上了CSDN热搜&#xff0c;这对科技类话题是非常难的存在。不光是做人工智能、机器学习的人关注&#xff0c;而是大量的各行各业从业人员都来关注这个模型&#xff0c;真可谓空前盛世。 我赶紧把…

无人驾驶路径规划论文简要

A Review of Motion Planning Techniques for Automated Vehicles综述和分类0Motion Planning for Autonomous Driving with a Conformal Spatiotemporal Lattice从unstructured环境向structured环境的拓展&#xff0c;同时还从state lattice拓展到了spatiotemporal lattice从而…

【数据结构】双向链表的接口实现(附图解和源码)

双向链表的接口实现&#xff08;附图解和源码&#xff09; 文章目录双向链表的接口实现&#xff08;附图解和源码&#xff09;前言一、定义结构体二、接口实现&#xff08;附图解源码&#xff09;1.初始化双向链表2.开辟新空间3.尾插数据4.尾删数据5.打印双向链表中数据6.头插数…

含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

吃瓜教程笔记—Task04

神经网络 知识点 M-P神经元 模型如图所示&#xff1a;  神经元的工作机理&#xff1a;神经元接收来到n个其他神经元传递过来的输入信号&#xff0c;这些输入信号通过带权重的连接进行传递&#xff0c;神经元接收到的总输入值将与神经元的阈值进行比较&#xff0c;然后通过…

Tesla Autopilot,处理器和硬件

作者 | 初光 出品 | 车端 备注 | 转载请阅读文中版权声明 知圈 | 进“汽车电子与AutoSAR开发”群&#xff0c;请加微“cloud2sunshine” 总目录链接>> AutoSAR入门和实战系列总目录 Tesla MOdelS/X 中有 60 多个处理器。其他型号的处理器较少&#xff0c;但数量仍然不少…

Nginx 全局变量

变量说明$host 域名部分 www.baidu.com/1.php?a1&b2 $document_uri 当前请求中不包含参数的uri www.baidu.com/1.php?a1&b2 $uri和 $document_uri 一样$args 请求中的参数。 www.baidu.com/1.php?a1&b2 $args是a1&b2 $request_uri 请求的URI。 www.baidu.co…

K8S常用命令速查手册

K8S常用命令速查手册一. K8S日常维护常用命令1.1 查看kubectl版本1.2 启动kubelet1.3 master节点执行查看所有的work-node节点列表1.4 查看所有的pod1.5 检查kubelet运行状态排查问题1.6 诊断某pod故障1.7 诊断kubelet故障方式一1.8 诊断kubelet故障方式二二. 端口策略相关2.1 …

UVM仿真环境搭建

环境 本实验使用环境为&#xff1a; Win10平台下的Modelsim SE-64 2019.2 代码 dut代码&#xff1a; module dut(clk,rst_n, rxd,rx_dv,txd,tx_en); input clk; input rst_n; input[7:0] rxd; input rx_dv; output [7:0] txd; output tx_en;reg[7:0] txd; reg tx_en;always…

洛谷P5737 【深基7.例3】闰年展示 C语言/C++

【深基7.例3】闰年展示 题目描述 输入 x,yx,yx,y&#xff0c;输出 [x,y][x,y][x,y] 区间中闰年个数&#xff0c;并在下一行输出所有闰年年份数字&#xff0c;使用空格隔开。 输入格式 输入两个正整数 x,yx,yx,y&#xff0c;以空格隔开。 输出格式 第一行输出一个正整数&a…

路漫漫:网络空间的监管趋势

网络空间是“以相互依存的网络基础设施为基本架构&#xff0c;以代码、信息与数据的流动为环境&#xff0c;人类利用信息通讯技术与应用开展活动&#xff0c;并与其他空间高度融合与互动的空间”。随着信息化技术的发展&#xff0c;网络空间日益演绎成为与现实人类生存空间并存…

Spring Cloud @RefreshScope 原理分析:代理类调用流程

背景 本文类分析 SpringCloud 的 RefreshScope 注解的 refresh 类型下&#xff0c;获取实例的过程。关键技术点&#xff1a; 扫描过程中对 RefreshScope 注解做了特殊处理&#xff0c;会额外注册两个BeanDefinition。GenericScope 实现了 BeanDefinitionRegistryPostProcesso…

[JVM]JVM内存模型,类加载过程,双亲委派模型

文章目录1. JDK,JRE,JVM分别是什么&#xff0c;它们之间有什么联系&#xff1f;2. JVM内存区域划分3. JVM类加载过程4. 一个经典面试题5. JVM 双亲委派模型1. JDK,JRE,JVM分别是什么&#xff0c;它们之间有什么联系&#xff1f; JDK: 是Java开发工具包&#xff0c;包含了编写&…

9、面向对象、泛型与反射

目录一、构造函数二、继承与重写三、泛型四、反射1 - 反射的基本概念2 - 反射的基础数据类型3 - 反射APIa - 获取Type类型b - 获取struct成员变量的信息c - 获取struct成员方法的信息d - 获取函数的信息e - 判断类型是否实现了某接口五、reflect.Valuea - 空value判断b - 获取V…