讲师中心 微信公众号
AI工具推荐 视频效率加速

Python typing.Annotated 类型注解的运行时处理与净化

陌磊同学_3395

陌磊同学_3395

发布时间:2025-11-06 14:43:10

|

400人浏览过

|

来源于php中文网

原创

python typing.annotated 类型注解的运行时处理与净化

本文探讨了如何在运行时从 `typing.Annotated` 类型中递归地移除注解信息,以获取其纯净的基础类型表示。通过介绍一个基于 `typing.get_origin` 和 `typing.get_args` 的递归函数,我们展示了如何遍历复杂的嵌套类型结构,将所有 `Annotated` 节点替换为其裸类型,从而实现类型表示的净化,避免了冗余注解在特定场景下的显示。

在 Python 的类型提示系统中,typing.Annotated 提供了一种强大的机制,允许开发者为类型添加额外的元数据(如描述、验证规则等),而这些元数据在运行时是可访问的。这对于构建依赖注入框架、API 文档生成或复杂数据验证等场景非常有用。然而,当这些带有注解的类型被嵌套使用时,它们的字符串表示可能会变得冗长且难以阅读,尤其是在需要打印或调试纯净类型结构时。

考虑以下类型别名:

from typing import Annotated, tuple, list

Point3D = Annotated[tuple[float, float, float], "A 3D Point"]
Points = Annotated[list[Point3D, list[float]], "A collection of points"]

直接打印 Points 会得到一个包含所有注解信息的复杂字符串:

立即学习“Python免费学习笔记(深入)”;

typing.Annotated[list[typing.Annotated[tuple[float, float, float], 'A 3D Point'] | list[float]], 'A collection of points']

如果我们的目标是获取其纯净的类型结构,例如 list[tuple[float, float, float] | list[float]],那么这种冗余的注解信息就会成为障碍。简单地使用 typing.get_args(Points)[0] 只能剥离最外层的 Annotated,而无法处理嵌套的注解。

Forge — Python Developer
Forge — Python Developer

Python开发助手 — 自动化脚本、API封装、命令行工具、数据管道、网页爬虫。经过测试的代码,包含错误处理和文档。当你需要...

下载

运行时净化 Annotated 类型

要解决这个问题,我们需要在运行时遍历整个类型结构,识别并处理所有的 Annotated 节点。Python 的 typing 模块提供了 get_origin 和 get_args 这两个函数,它们是解析泛型类型结构的关键工具。

  • typing.get_origin(type_object): 对于泛型类型(如 list[int]),它返回泛型类型本身(list)。对于非泛型类型或没有参数的类型,它返回 None。
  • typing.get_args(type_object): 对于泛型类型(如 list[int]),它返回一个包含所有类型参数的元组((int,))。对于非泛型类型,它返回一个空元组 ()。

利用这两个函数,我们可以构建一个递归函数来“净化”类型对象,即将其中的所有 Annotated 节点替换为其基础类型。

实现类型净化函数

以下是实现这一功能的 Python 函数:

from typing import Annotated, get_args, get_origin, Union

def convert_annotated_to_bare_types(type_object: type):
  """
  递归地将类型对象中所有 `typing.Annotated` 节点转换为其纯净的基础类型。

  Args:
    type_object: 待处理的类型对象。

  Returns:
    移除了所有 `Annotated` 注解的纯净类型对象。
  """
  origin, args = get_origin(type_object), get_args(type_object)

  # 1. 基本情况:如果类型没有 origin (即不是泛型或没有参数),则直接返回。
  # 例如:int, float, str 等。
  if origin is None:
    return type_object

  # 2. 处理 Annotated 类型:
  # 如果 origin 是 Annotated,我们只关心它的第一个参数(即实际的类型)。
  # 对这个实际类型递归调用本函数,以处理其内部可能存在的嵌套 Annotated。
  if origin is Annotated:
    bare_type = get_args(type_object)[0]
    return convert_annotated_to_bare_types(bare_type)

  # 3. 处理其他泛型类型(如 list, dict, Union 等):
  # 对所有类型参数递归调用本函数,以净化它们。
  # 然后使用 origin 和净化后的参数重建泛型类型。
  converted_args = [
    convert_annotated_to_bare_types(arg) for arg in args
  ]

  # 特殊处理 Union 类型,因为 Union[*args] 语法在 Python 3.9+ 才能使用
  # 对于旧版本,可能需要 Union[arg1, arg2]
  if origin is Union:
      # Union[X, Y] 等同于 X | Y
      if not converted_args:
          return type(None) # Union without args is effectively None
      if len(converted_args) == 1:
          return converted_args[0]
      # Python 3.9+ 推荐使用 X | Y 语法,但为了兼容性,Union[*args] 也是可行的
      # 这里的 origin[*converted_args] 能够正确处理 Union
      return origin[*converted_args]

  # 对于其他泛型类型,直接使用 origin[*converted_args] 重建
  return origin[*converted_args]

示例应用

现在,让我们使用这个函数来净化之前定义的 Points 类型:

# 重新定义类型以便运行示例
Point3D = Annotated[tuple[float, float, float], "A 3D Point"]
Points = Annotated[list[Point3D | list[float]], "A collection of points"] # 注意这里将 Union 改为 | 语法以更清晰

# 原始的 Points 类型表示
print(f"原始类型: {Points}")

# 净化后的类型
cleaned_points_type = convert_annotated_to_bare_types(Points)
print(f"净化后类型: {cleaned_points_type}")

# 预期输出:
# 原始类型: typing.Annotated[list[typing.Annotated[tuple[float, float, float], 'A 3D Point'] | list[float]], 'A collection of points']
# 净化后类型: list[tuple[float, float, float] | list[float]]

从输出可以看出,所有 Annotated 信息已被成功移除,我们得到了一个纯净且易于理解的类型表示。

注意事项与总结

  1. 运行时操作:这个净化过程是在运行时进行的。原始的 Annotated 类型定义仍然保留其注解信息,这使得我们可以在其他需要这些元数据的场景下继续使用它们。
  2. 通用性:该方法不依赖于正则表达式,而是利用 typing 模块提供的标准API来解析类型结构,因此更加健壮和准确,能够处理任意深度的嵌套和复杂的泛型组合。
  3. 应用场景:此技术适用于需要生成简洁类型表示的场景,例如:
    • 动态生成 API 文档时,只显示核心类型结构。
    • 在某些数据验证或序列化库中,需要获取不含元数据的基础类型。
    • 调试时,获取更清晰的类型输出。

通过这种递归遍历和重构类型对象的方法,我们能够有效地管理 typing.Annotated 带来的类型信息丰富性与类型表示简洁性之间的平衡,确保在不同需求下都能获得最合适的类型视图。

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4356

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

2881

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

7922

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

812

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

520

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

673

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

386

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

719

2023.12.06

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

80

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn