Python学习之-typing详解

前言:

Python的typing模块自Python 3.5开始引入,提供了类型系统的扩展,能够帮助程序员定义变量、函数的参数和返回值类型等。这使得代码更易于理解和检查,也方便了IDE和一些工具进行类型检查,提升了代码的质量。

typing 模块概述

typing 模块是 Python 标准库中用于支持类型提示的模块。它提供了一系列的类型和类型相关的工具,帮助开发者在代码中添加类型提示,以提高代码的可读性和可靠性。

1 类型提示的基本使用

1.1 变量类型注解:

age: int = 25
name: str = "Alice"

1.2函数参数和返回值类型注解:

def greet(name: str) -> str:return "Hello, " + name

1.3列表、字典等复杂类型注解:

from typing import List, Dictnumbers: List[int] = [1, 2, 3]
user_info: Dict[str, str] = {"name": "Alice", "age": "25"}

2 常见的typing模块类型

List[T],Set[T],Dict[K, V]等:用于注解容器类型,T、K、V分别代表容器内元素类型,字典的键和值类型。

2.1 Tuple[T, …]:用于定长元组。

from typing import Tuplecoordinate: Tuple[int, int, int] = (10, 20, 30)

2.2 Optional[T]:用于表示某个类型或None。

from typing import Optionaldef get_age(name: str) -> Optional[int]:if name == "Alice":return 25return None

2.3 Union[T, U, …]:当一个参数可能是多种类型之一时使用。

from typing import Uniondef log_message(message: Union[str, int]) -> None:print(message)

2.4 Callable[[Arg1Type, Arg2Type], ReturnType]:用于表示可调用对象(如函数)的类型签名。

from typing import Callabledef add(a: int, b: int) -> int:return a + bcalculator: Callable[[int, int], int] = add

3 Type Hints的高级应用

3.1 泛型:在定义类或函数时,允许使用类型参数。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/17
# @Author  : Summer
# @File    :
# @describe:
"""
from typing import TypeVar, Generic, ListT = TypeVar('T')class Stack(Generic[T]):def __init__(self) -> None:self._container: List[T] = []def push(self, item: T) -> None:self._container.append(item)def pop(self) -> T:return self._container.pop()stack = Stack[int]()
stack.push(1)
print(stack.pop())  # 输出1

上述代码的解析:首先从typing模块导入TypeVar、Generic和List。这些是实现自定义泛型类型的核心组件。
T = TypeVar(‘T’):使用TypeVar创建一个类型变量T。这个变量将用于表示Stack类可以接受的元素的类型。TypeVar是定义泛型类和函数时的占位符,表示可以是任意类型。
class Stack(Generic[T]):定义了一个名为Stack的类,这个类是泛型的,可以存储类型为T的元素。这里的T是在之前用TypeVar定义的类型变量。Generic[T]表示Stack是一个泛型类,它的行为可以基于不同的类型T进行参数化。
在__init__方法中,初始化了一个名为_container的列表,这个列表是用于存储栈中元素的容器。List[T]表示_container是一个列表,其中可以存储任意类型为T的元素。
stack = Stackint创建了一个Stack的实例stack,指定T为int类型。这意味着这个stack实例是一个整型的栈,只能存储整数。
通过push方法向栈中压入一个整数1。
通过pop方法从栈中弹出最后一个元素,也就是之前压入的整数1。
这段代码展示了如何使用Python的typing模块创建泛型数据结构,使得这个数据结构变得更加通用和灵活。它可以在保持类型安全的同时,被用于存储任何指定类型的数据。

3.2 NewType:

用于定义新类型,以帮助区分具有相同基础类型但应用场景不同的场合。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/17
# @Author  : Summer
# @File    :
# @describe:
"""
from typing import NewTypeUserId = NewType('UserId', int)def get_user_name(user_id: UserId) -> str:return "User#" + str(user_id)user_id = UserId(524313)
print(get_user_name(user_id))  # User#524313

user_id = UserId(524313):使用UserId类型创建一个新的用户ID实例。注意,尽管UserId是基于int的一个新类型,但是这一步看起来和直接对整数进行类型转换(如int(x))相似。然而,UserId(524313)在类型检查时被视为一个与int不同的独立类型。
print(get_user_name(user_id))调用get_user_name函数,并传入之前创建的user_id。然后打印函数的返回值,预期输出为"User#524313"。

4 类型检查工具

typing 模块还提供了一些用于类型检查的工具,如 isinstance()、issubclass() 等。

from typing import Listdef is_valid_input(data: List) -> bool:return isinstance(data, List)print(is_valid_input(data=1))  # False
print(is_valid_input(data=[1, 2, 3]))  # True

5 结构化类型和协议

Python 的 typing 模块还支持结构化类型和协议,用于表示对象的形状或接口。可以使用 Protocol 类来定义一个协议,并在参数类型注解中使用。
举个例子,如果我们想定义一个Writable的协议,所有满足这个协议的对象都应该有一个write方法。这里是如何使用Protocol来做这件事的:

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/17
# @Author  : Summer
# @File    :
# @describe:
"""
from typing import Protocolclass Writable(Protocol):def write(self, data: str) -> int:...# 实现了 Writable 接口的类
class FileWriter:def write(self, data: str) -> int:print(f"Writing {data} to file.")return len(data)  # 假设返回写入的字节数# 实现了 Writable 接口的类
class StringWriter:def write(self, data: str) -> int:print(f"Writing {data} to string buffer.")return len(data)  # 假设返回写入的字节数# 函数接受任何实现了Writable接口的对象
def write_data(writer: Writable, data: str):num_bytes_written = writer.write(data)print(f"Wrote {num_bytes_written} bytes.")return# FileWriter和StringWriter没有从Writable显式继承,但它们实现了Writable协议
file_writer = FileWriter()
string_writer = StringWriter()# 可以传递给write_data函数,因为它们符合Writable协议
write_data(file_writer, "Hello, World!")
write_data(string_writer, "Hello, Python!")

Writable(Protocol)定义了一个需要有write方法的协议,该方法接受一个字符串data并返回一个整数。
类FileWriter和StringWriter都有一个write方法,这意味着它们“符合”Writable协议。注意,我们没有明确地让FileWriter或StringWriter类继承Writable协议。
函数write_data接受Writable类型的参数writer。这意味着任何实现了write方法的对象都可以传递给这个函数。
最后,创建了FileWriter和StringWriter的实例,然后将它们传递给write_data函数,展示了如何在不使用继承的情况下通过协议来实现接口兼容性。
这种方式的好处是可以让你的代码更加灵活,并且它鼓励更好的分离关注点。另外,由于它基于鸭子类型,所以它对于一些动态编程模式也非常有用,例如在mocking或依赖注入中。

小结:

Python的typing模块为静态类型检查提供了强大的支持,通过在代码中添加类型注解,不仅可以提高代码的可读性,还可以利用静态类型检查工具(如mypy)来发现潜在的错误。随着Python生态的发展,类型提示已经成为Python编程的一个重要部分。
如果你觉得文章还不错,请大家 点赞、分享、留言 ,因为这将是我持续输出更多优质文章的最强动力!当然如果有小伙伴需要python、java、性能等等相关的学习资料的也可以私聊我获取哈,都是本人之前收集的一些学习资料,都可以免费提供给大家学习,希望能对大家有帮助。
在这里插入图片描述

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

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

相关文章

【每日刷题】Day17

【每日刷题】Day17 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) 2. 162. 寻找峰值 - 力扣…

Scratch四级:第02讲 字符串

第02讲 字符串 教练:老马的程序人生 微信:ProgrammingAssistant 博客:https://lsgogroup.blog.csdn.net/ 讲课目录 运算模块:有关字符串的积木块遍历字符串项目制作:“解密”项目制作:“成语接龙”项目制作:“加减法混合运算器”字符串 计算机学会(GESP)中属于三级的内…

YOLOv9改进策略 | 损失函数篇 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv9的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的…

腾讯AI Lab:“自我对抗”提升大模型的推理能力

本文介绍了一种名为“对抗性禁忌”(Adversarial Taboo)的双人对抗语言游戏,用于通过自我对弈提升大型语言模型的推理能力。 👉 具体的流程 1️⃣ 游戏设计:在这个游戏中,有两个角色:攻击者和防守…

基于Ultrascale+系列GTY收发器64b/66b编码方式的数据传输(一)——Async Gearbox使用及上板测试

于20世纪80年代左右由IBM提出的传统8B/10B编码方式在编码效率上较低(仅为80%),为了提升编码效率,Dgilent Techologies公司于2000年左右提出了64b/66b编码并应用于10G以太网中。Xilinx GT手册中没有过多64b/66b编码介绍&#xff0c…

绝地求生:PUBG地形破坏功能上线!分享你的游玩感受及反馈赢丰厚奖励

随着29.1版本更新,地形破坏功能及新道具“镐”正式在荣都地图亮相!大家现在可以在荣都地图体验“动手挖呀挖”啦。 快来分享你的游玩感受及反馈,即可参与活动赢取精美奖励! 参与方式 以发帖/投稿的形式,在 #一决镐下#…

【记录】Python|Selenium 下载 PDF 不预览不弹窗(2024年)

版本: Chrome 124Python 12Selenium 4.19.0 版本与我有差异不要紧,只要别差异太大比如 Chrome 用 57 之前的版本了,就可以看本文。 如果你从前完全没使用过、没安装过Selenium,可以参考这篇博客《【记录】Python3|Sele…

kafka---topic详解

一、分区与高可用 在Kafka中,事件(events 事件即消息)是以topic的形式进行组织的;同时topic是分区(partitioned)的,这意味着一个topic分布在Kafka broker上的多个“存储桶”(buckets)上。这种数据的分布式放置对于可伸缩性非常重要,因为它允许客户端应用程序同时从多个…

Stable Diffusion WebUI 控制网络 ControlNet 插件实现精准控图-详细教程

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 大家好,我是水滴~~ 本文主要介绍 Stable Diffusion WebUI 一个比较重要的插件 ControlNet(控制网络),主…

PHP货运搬家/拉货小程序二开源码搭建的功能

运搬家/拉货小程序的二次开发可以添加许多功能,以增强用户体验和提高业务效率。以下是一些可能的功能: 用户端功能: 注册登录:允许用户创建个人账户并登录以使用应用程序。货物发布:允许用户发布他们需要搬运的货物信息…

HTML转EXE 各平台版本(Windows, IOS, Android)

前言: 在几年前,我在盒子论坛中看到有人提供了一个将HTML打包成EXE文件的程序的软件,好像是外国人做的,该软件是收费的。当时我在想,这个功能不是很难实现呀,于是我就有了开发一个HTML转EXE的工具想法&…

数据可视化-ECharts Html项目实战(13)

在之前的文章中,我们深入学习ECharts动态主题切换和自定义ECharts主题。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错,请留下你宝贵的点赞,谢谢。 数据可视化-ECharts Html项…

写后端项目的分页查询时,解决分页不更新

写基于VueSpringBoot项目,实现分页查询功能时,改完代码后,发现页数不更新: 更改处如下: 显示如图: 发现页数没有变化,两条数据还是显示在同一页,而且每页都10条。且重启项目也没有更…

零基础小白,如何入门计算机视觉?

目录 前言 计算机视觉技术学习路线 基础知识 1. 数学基础 2. 编程基础 3. 图像处理基础 基础算法与技术 1. 特征提取与描述符 2. 图像分割与对象检测 3. 三维重建与立体视觉 机器学习与深度学习 1. 机器学习基础 2. 深度学习 高级主题与应用 1. 高级机器学习与深度学习 2. 计算…

论文笔记:Are Human-generated Demonstrations Necessary for In-context Learning?

iclr 2024 reviewer 评分 6668 1 intro 大型语言模型(LLMs)已显示出在上下文中学习的能力 给定几个带注释的示例作为演示,LLMs 能够为新的测试输入生成输出然而,现行的上下文学习(ICL)范式仍存在以下明显…

简述PDF原理和实践

Hello,我是小恒不会java。 由于最近有输出PDF报表的项目需求,所以复习一下PDF到底是什么,该如何产生,如何应用至项目中。 更多参见Adobe官方文档(https://www.adobe.com/cn/) PDF原理 PDF(Port…

机器学习实验二-----决策树构建

决策树是机器学习中一种基本的分类和回归算法,是依托于策略抉择而建立起来的树。本文学习的是决策树的分类 1. 构建决策树流程 选择算法:常用的算法包括ID3、C4.5、CART等。 划分节点:根据数据特征和算法选择,递归地划分节点&…

亚信安全数据安全运营平台DSOP新版本发布 注入AI研判升维

在当今快速发展的数字经济时代,企业对于数据的依赖日益加深,数据安全已成为企业的生命线。亚信安全推出数据安全运营平台DSOP全新版本,正是为满足企业对数据安全的高度需求而设计。这款平台以其卓越的能力和技术优势,为企业的数据…

漂亮的七彩引导页导航HTML源码

源码介绍 漂亮的七彩引导页导航HTML源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 效果截图 源码下载 漂亮的七彩…

notepad++安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Notepad是一款开源的、免费的文本编辑器,它最初由侯今吾基于Scintilla文本编辑组件独立研发。Notepad以GPL发布,并拥有完整的中文化接口,支持多国语言编写的功能(采用UTF8技术&…