跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在 Python 中访问 Annotated 类型提示的元数据

本文介绍如何通过 `annotated.__metadata__` 属性安全、标准地提取类型注解中携带的自定义元数据(如文档对象、验证规则等),避免字符串化陷阱,适用于生成 api 文档、运行时校验等场景。 在 Python 3.9+ 中,typing.Annotated 提供了一种标准化方式,为类型添加任意元数据(metadata),而这些元数据并非类型本身的一部分,而是作为额外信息附着在类型上。关键在于: Annotated 类型对象暴露了 __metadata__ 属性,它是一个只读元组,包含除基础类型外的所有后续参数 ——这正是访问你传入的 B(x="foo") 实例的正确入口。 以下是一个完整、可运行的示例:
from typing import Annotated, get_args from dataclasses import dataclass import inspect @dataclass class B: x: str @dataclass class A: y: Annotated[str, B(x="foo"), "A descriptive tag"] # 获取运行时解析后的注解字典(推荐使用 get_type_hints 或 inspect.get_annotations) annotations = inspect.get_annotations(A, eval_str=True) # 提取 Annotated 类型 annotated_type = annotations["y"] # ✅ 正确方式:访问 __metadata__ 属性 if hasattr(annotated_type, '__metadata__'): metadata = annotated_type.__metadata__ print("Metadata tuple:", metadata) # 输出: (B(x='foo'), 'A descriptive tag') # 获取第一个元数据项(即你的 B 实例) if metadata: b_instance = metadata[0] if isinstance(b_instance, B): print("B.x =", b_instance.x) # 输出: B.x = foo
⚠️ 注意事项: Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 __metadata__ 是 Annotated 类型对象的 实例属性 ,仅当类型确实是 Annotated[...] 时才存在;务必先用 hasattr(..., '__metadata__') 或 isinstance(..., types.GenericAlias) + 检查 __origin__ is Annotated 做安全判断; inspect.get_annotations(..., eval_str=True) 是获取已求值注解的推荐方式(尤其含字符串前向引用时),但需确保模块上下文可用; 不要尝试通过 str() 或 repr() 解析注解字符串——这不可靠且易受格式变更影响; 若需批量处理(如框架级文档生成),建议封装工具函数:
def get_annotated_metadata(tp): """安全提取 Annotated 元数据,返回 None 若非 Annotated 类型""" if hasattr(tp, '__metadata__') and hasattr(tp, '__origin__') and tp.__origin__ is Annotated: return tp.__metadata__ return None # 使用示例 meta = get_annotated_metadata(annotations["y"]) if meta: for item in meta: print("Metadata item:", item)
总结:Annotated.__metadata__ 是官方支持、稳定可靠的元 数据访问 机制,是构建类型驱动文档、校验、序列化等高级功能的基础。始终优先使用该属性而非字符串操作或 AST 解析,以保证代码健壮性与可维护性。 立即学习 “ Python免费学习笔记(深入) ”;

相关文章