python小知识-typing注解你的程序

news2025/2/2 8:38:30

python小知识-typing注解你的程序

1. Typing的简介

typing 是 Python 的一个标准库,它提供了类型注解的支持,但并不会强制类型检查。类型注解在 Python 3.5 中引入,并在后续版本中得到了增强和扩展。typing 库允许开发者为变量、函数参数和返回值等提供预期的类型信息,这有助于代码的可读性、可维护性和文档化。此外,一些第三方工具(如 MyPy)可以使用这些类型注解进行静态类型检查。

2. Typing的基本使用

基本使用包括为变量、函数参数和返回值添加类型注解。

from typing import List, Dict, Union

# 变量类型注解
def greet(name: str) -> None:
    print(f"Hello, {name}!")

# 使用类型注解的变量
names: List[str] = ["Alice", "Bob", "Charlie"]

# 字典的类型注解
person_info: Dict[str, int] = {"name": "John", "age": 30}  # 注意:这里只是示例,实际中"name"应为str类型
# 正确的字典类型注解
person_info: Dict[str, Union[str, int]] = {"name": "John", "age": 30}  # 需要导入Union

可以看出第一个person_info并没有报错,只是注解的不对,可以正常使用。

Typing还提供了元组Tuple和可选类型Optional

Tuple 允许你为元组中的每个元素指定类型。

from typing import Tuple

# 定义一个包含两个整数的元组类型
IntPair = Tuple[int, int]

# 创建一个符合 IntPair 类型的元组
coordinate: IntPair = (10, 20)

# 函数返回元组
def get_coordinates() -> IntPair:
    return 1, 2

# 调用函数并访问返回的元组
x, y = get_coordinates()
print(f"Coordinates: ({x}, {y})")

Optional 表示一个值可以是某个类型或者 None

from typing import Optional

# 定义一个函数,其参数可能是字符串或None
def greet_optional(name: Optional[str] = None) -> None:
    if name is None:
        print("Hello, anonymous user!")
    else:
        print(f"Hello, {name}!")

# 调用函数,传入一个字符串
greet_optional("Alice")  # 输出: Hello, Alice!

# 调用函数,不传入任何参数(使用默认值None)
greet_optional()  # 输出: Hello, anonymous user!

3. 泛型的使用

泛型允许你编写灵活且可重用的代码,其中类型参数可以是任何类型。

在Python的typing库中,泛型(Generics)是一个非常重要的概念,它允许我们编写更加灵活和可重用的代码。泛型的主要意义和作用体现在以下几个方面:

提高代码复用性

泛型允许我们编写不依赖于具体类型的代码。通过定义类型参数(Type Parameters),我们可以创建可重用的类、函数和容器,这些结构能够处理任何数据类型。这样,我们就可以避免为每种类型重复编写相同的代码。

类型安全

虽然Python是一种动态类型语言,但在某些情况下,类型安全对于减少错误和提高代码质量非常重要。泛型提供了一种在编译时(或静态分析时)检查类型安全性的方法。通过使用泛型,我们可以确保传递给函数或类的参数类型是正确的,从而避免运行时错误。

提高代码可读性

泛型可以使代码更具描述性和可读性。通过明确指定泛型类型参数,我们可以使代码更清晰地表达其意图,这对于维护和理解代码非常有帮助。

容器类型抽象

泛型在容器类型(如列表、集合、字典等)的抽象中特别有用。通过使用泛型,我们可以定义能够处理任何数据类型的容器,而无需为每种类型单独编写代码。例如,我们可以定义一个泛型列表类,该类可以存储任何类型的元素,并提供统一的接口来操作这些元素。

泛型约束和类型推断

泛型还支持类型约束和类型推断。通过指定类型参数的上界或下界,我们可以限制可以传递给泛型结构的数据类型范围。此外,某些情况下,类型推断可以帮助我们自动推断出泛型类型参数的实际类型,从而简化代码编写。

下面是一个使用泛型实现栈的简单示例:

from typing import TypeVar, Generic, List

T = TypeVar('T')  # 声明一个类型变量T

class Stack(Generic[T]):
    def __init__(self):
        self.items: List[T] = []  # 泛型列表用于存储栈中的元素

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        if not self.items:
            raise IndexError("pop from an empty stack")
        return self.items.pop()

# 使用整型栈
int_stack = Stack[int]()
int_stack.push(1)
int_stack.push(2)
print(int_stack.pop())  # 输出: 2

# 使用字符串栈
str_stack = Stack[str]()
str_stack.push("hello")
str_stack.push("world")
print(str_stack.pop())  # 输出: world

在上面的示例中,我们定义了一个泛型栈类Stack,它使用类型变量T来表示栈中元素的类型。通过指定不同的类型参数(如intstr),我们可以创建不同类型的栈,并享受泛型带来的代码复用性和类型安全性。

4. 自定义新的类型

虽然 typing 库已经提供了许多内置的类型注解,但你也可以使用 NewType 来创建新的类型别名,这些别名在类型检查时会视为不同的类型。

from typing import NewType

UserId = NewType('UserId', int)

def get_user_name(user_id: UserId) -> str:
    # 假设有一个根据用户ID获取用户名的函数
    pass

# 正确使用
user_id: UserId = UserId(123)
get_user_name(user_id)

# 错误使用(类型不匹配)
get_user_name(123)  # 如果使用MyPy等类型检查工具,这里会报错

5. 总结

typing 库是 Python 中非常重要的一个库,它提供了类型注解的支持,使得代码更加清晰、易于理解和维护。通过使用 typing 库,我们可以为变量、函数参数和返回值等添加类型信息,从而提高代码的可读性和可维护性。此外,泛型的使用可以让我们编写更加灵活和可重用的代码。最后,通过自定义新的类型别名,我们可以进一步细化类型信息,提高代码的类型安全性。

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

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

相关文章

HTML<hgroup>标签

例子&#xff1a; 使用hgroup元素标记标题和段落是相关的&#xff1a; <hgroup> <h2>Norway</h2> <p>The land with the midnight sun.</p> </hgroup> 定义和用法&#xff1a; 标签<hgroup>用于包围标题和一个或多个<p&g…

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本&#xff0c;美食/KTV的主页能正常返回&#xff0c;但无法显示内容 上次好不容易升到了5.0以上版本&#xff0c;现在又用不了了 Redis 6.2的windo…

mybatis辅助配置

驼峰映射 sql里面定义字段通常是使用下划线定义 比如dept_id 而我们的后端属性通常就是驼峰命名 deptId 所以这两匹配进行自动赋值就比较麻烦 可以使用 select dept_id as deptId 来解决&#xff08;起别名&#xff09; 也可以用mybatis的辅助配置解决 第三种就是推荐的在spr…

基于YOLO11的肺结节检测系统

基于YOLO11的肺结节检测系统 (价格90) LUNA16数据集 数据一共 1186张 按照8&#xff1a;1&#xff1a;1随机划分训练集&#xff08;948张&#xff09;、验证集&#xff08;118张&#xff09;与测试集&#xff08;120张&#xff09; 包含 nodule 肺结节 1种…

C#面向对象(继承)

1.什么是继承 在 C# 编程语言中&#xff0c;继承是一个核心概念&#xff0c;它允许一个类&#xff08;称为派生类&#xff09;继承另一个类&#xff08;称为基类&#xff09;的成员&#xff0c;如方法、属性和其他成员。继承机制使得代码重用成为可能&#xff0c;简化了应用程…

Qt事件处理:理解处理器、过滤器与事件系统

1. 事件 事件 是一个描述应用程序中、发生的某些事情的对象。 在 Qt 中&#xff0c;所有事件都继承自 QEvent &#xff0c;并且每个事件都有特定的标识符&#xff0c;如&#xff1a;Qt::MouseButtonPress 代表鼠标按下事件。 每个事件对象包含该事件的所有相关信息&#xff…

为大模型提供webui界面的利器:Open WebUI 完全本地离线部署deepseek r1

为大模型提供webui界面的利器&#xff1a;Open WebUI Open WebUI的官网&#xff1a;&#x1f3e1; Home | Open WebUI 开源代码&#xff1a;WeTab 新标签页 Open WebUI是一个可扩展、功能丰富、用户友好的自托管AI平台&#xff0c;旨在完全离线运行。它支持各种LLM运行程序&am…

17.1 图像操作

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 17.1.1 Image类 Image类为源自 Bitmap 和 Metafile 的类提供功能的抽象基类。 Image的属性大多数是只读的&#xff1a; FrameDim…

软件工程概论试题五

一、多选 1.好的软件的基本属性包括()。 A. 效率 B. 可依赖性和信息安全性 C. 可维护性 D.可接受性 正答&#xff1a;ABCD 2.软件工程的三要素是什么()? A. 结构化 B. 工具 C.面向对象 D.数据流! E.方法 F.过程 正答&#xff1a;BEF 3.下面中英文术语对照哪些是正确的、且是属…

深入解析“legit”的地道用法——从俚语到正式表达:Sam Altman用来形容DeepSeek: legit invigorating(真的令人振奋)

深入解析“legit”的地道用法——从俚语到正式表达 一、引言 在社交媒体、科技圈甚至日常对话中&#xff0c;我们经常会看到或听到“legit”这个词。比如最近 Sam Altman 在 X&#xff08;原 Twitter&#xff09;上发的一条帖子中写道&#xff1a; we will obviously deliver …

行业规范要当作业务实体画出来吗

第五元素 总觉得这些没有逻辑的实体&#xff0c;在绘制的时候不应该绘出来&#xff0c;他们没有责任啊。 比如以下:查阅规范 感觉不太对 UMLChina潘加宇 你这个规范是一个电脑系统还是一本书 第五元素 是书 UMLChina潘加宇 书没有智能&#xff0c;唯一暴露的接口是“翻”…

Cubemx文件系统挂载多设备

cubumx版本&#xff1a;6.13.0 芯片&#xff1a;STM32F407VET6 在上一篇文章中介绍了Cubemx的FATFS和SD卡的配置&#xff0c;由于SD卡使用的是SDIO通讯&#xff0c;因此具体驱动不需要自己实现&#xff0c;Cubemx中就可以直接配置然后生成SDIO的驱动&#xff0c;并将SD卡驱动和…

[Linux]从零开始的STM32MP157 U-Boot移植

一、前言 在上一次教程中&#xff0c;我们了解了STM32MP157的启动流程与安全启动机制。我们还将FSBL的相关代码移植成功了。大家还记得FSBL的下一个步骤是什么吗&#xff1f;没错&#xff0c;就是SSBL&#xff0c;而且常见的我们将SSBL作为存放U-Boot的地方。所以本次教程&…

前端 | 深入理解Promise

1. 引言 JavaScript 是一种单线程语言&#xff0c;这意味着它一次仅能执行一个任务。为了处理异步操作&#xff0c;JavaScript 提供了回调函数&#xff0c;但是随着项目处理并发任务的增加&#xff0c;回调地狱 (Callback Hell) 使异步代码很难维护。为此&#xff0c;ES6带来了…

【数据结构】_链表经典算法OJ:合并两个有序数组

目录 1. 题目描述及链接 2. 解题思路 3. 程序 3.1 第一版 3.2 第二版 1. 题目描述及链接 题目链接&#xff1a;21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。 新链表是通过拼接给…

C++ 字母大小写转换两种方法统计数字字符的个数

目录 题目&#xff1a; 代码1&#xff1a; 代码2&#xff1a; 题目&#xff1a; 大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。 输入格式 输入一行&#x…

终极版已激活!绿话纯净,打开即用!!!

今天我想和大家聊聊一个非常实用的工具——视频转换大师最终版。 视频转换大师终极版&#xff0c;堪称一款全能型的视频制作神器&#xff0c;集视频转换与编辑功能于一体。它搭载的视频增强器技术&#xff0c;能够最大限度地保留原始视频质量&#xff0c;甚至还能实现质量的进…

【2025年最新版】Java JDK安装、环境配置教程 (图文非常详细)

文章目录 【2025年最新版】Java JDK安装、环境配置教程 &#xff08;图文非常详细&#xff09;1. JDK介绍2. 下载 JDK3. 安装 JDK4. 配置环境变量5. 验证安装6. 创建并测试简单的 Java 程序6.1 创建 Java 程序&#xff1a;6.2 编译和运行程序&#xff1a;6.3 在显示或更改文件的…

C++ strcpy和strcat讲解

目录 一. strcpy 代码演示&#xff1a; 二.strcat 代码演示&#xff1a; 一. strcpy 使⽤字符数组可以存放字符串&#xff0c;但是字符数组能否直接赋值呢&#xff1f; ⽐如&#xff1a; char arr1[] "abcdef"; char arr2[20] {0}; arr2 arr1;//这样这节赋值可…

STM32 01 LED

一、点亮一个LED 在STC-ISP中单片机型号选择 STC89C52RC/LE52RC&#xff1b;如果没有找到hex文件&#xff08;在objects文件夹下&#xff09;&#xff0c;在keil中options for target-output- 勾选 create hex file。 如果要修改编程 &#xff1a;重新编译-下载/编程-单片机重…