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

embedded/2025/2/3 0:13:50/

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

1. Typing的简介

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

2. Typing的基本使用

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

python">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 允许你为元组中的每个元素指定类型。

python">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

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

提高代码可读性

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

容器类型抽象

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

泛型约束和类型推断

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

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

python">from typing import TypeVar, Generic, ListT = TypeVar('T')  # 声明一个类型变量Tclass 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 来创建新的类型别名,这些别名在类型检查时会视为不同的类型。

python">from typing import NewTypeUserId = 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.ppmy.cn/embedded/159043.html

相关文章

受限玻尔兹曼机:原理、实现、与神经网络对比及应用

本文要点 受限玻尔兹曼机(Restricted Boltzmann Machine, RBM)是一种强大的生成式随机神经网络,在机器学习和深度学习领域有着广泛的应用。本文将深入探讨受限玻尔兹曼机的原理,详细介绍其与玻尔兹曼分布的关系、“受限”的含义以…

【C语言】static关键字的三种用法

【C语言】static关键字的三种用法 C语言中的static关键字是一个存储类说明符,它可以用来修饰变量和函数。static关键字的主要作用是控制变量或函数的生命周期和可见性。以下是static关键字的一些主要用法和含义: 局部静态变量: 当static修饰…

页高速缓存与缓冲区缓存的应用差异

页高速缓存(Page Cache)与缓冲区缓存(Buffer Cache)是计算机系统中用于提高数据访问性能的两种不同类型的缓存机制,它们的差异主要体现在以下几个方面: 缓存目的 页高速缓存:主要用于加速对磁…

Electron使用WebAassembly实现CRC-8 MAXIM校验

Electron使用WebAssembly实现CRC-8 MAXIM校验 将C/C语言代码,经由WebAssembly编译为库函数,可以在JS语言环境进行调用。这里介绍在Electron工具环境使用WebAssembly调用CRC-8 MAXIM格式校验的方式。 CRC-8 MAXIM校验函数WebAssebly源文件 C语言实现CR…

记录一次Sqoop从MySQL导入数据到Hive问题的排查经过

个人博客地址:记录一次Sqoop从MySQL导入数据到Hive问题的排查经过 | 一张假钞的真实世界 问题描述 MySQL中原始数据有790W+的记录数,在Sqoop抽取作业成功的情况下在Hive中只有500W左右的记录数。 排查过程 数据导入脚本Log 通过Log可以发现以下信息: 该Sqoop任务被分解…

深入了解 HTTP 头部中的 Accept-Encoding:gzip、deflate、br、zstd

在现代Web开发中,性能优化是至关重要的一部分。HTTP协议中的Accept-Encoding头部正是为性能提升提供了一个非常有效的方式,它告知服务器客户端能够理解并接收哪些压缩算法的响应内容。在这篇博客中,我们将详细探讨Accept-Encoding头部的作用&…

go到底是什么意思:对go的猜测或断言

go这个单词,简单地讲,表示“走或去”的意思: go v.去;走 认真想想,go是一个非常神秘的单词,g-和o-这两个字母,为什么就会表达“去;走”的意思呢?它的字面义或本质&…

cursor软件的chat和composer分别是什么

Cursor 是一款基于人工智能的代码编辑器,集成了类似 ChatGPT 的功能,旨在帮助开发者更高效地编写代码。以下是 Cursor 中 Chat 和 Composer 的具体功能: 1. Chat Cursor 中的 Chat 是一个基于 AI 的聊天功能,类似于 ChatGPT&…