如何在 Python 中提取 Annotated 类型提示中的元数据信息

来源:开发教程作者:广州网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在 Python 中提取 Annotated 类型提示中的元数据信息》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在 Python 中提取 Annotated 类型提示中的元数据信息》有用,将其分享出去将是对创作者最好的鼓励。

在Python的类型提示体系中,Annotated是一个可以让我们为类型标注附加额外元数据的重要工具,它定义在typing模块中,能够在不影响类型检查的前提下,为变量、函数参数、返回值等添加自定义的补充信息,这些信息在很多场景下都能发挥重要作用,比如参数校验、序列化规则定义、接口文档生成等。提取Annotated中的元数据信息,是发挥这些附加信息价值的关键步骤。

如何在 Python 中提取 Annotated 类型提示中的元数据信息

Annotated的基本使用方式

Annotated的语法结构为Annotated[基础类型, 元数据1, 元数据2, ...],其中第一个参数是基础的类型标注,后面的参数都是附加的元数据,元数据可以是任意类型的对象,比如字符串、数字、自定义类的实例等。下面是一个简单的使用示例:

from typing import Annotated

# 为int类型附加最小值和最大值的元数据
Age = Annotated[int, 0, 120]
# 为str类型附加长度限制的元数据
Username = Annotated[str, 6, 20]

提取Annotated元数据的核心方法

要提取Annotated中的元数据,我们需要借助typing模块提供的get_type_hints函数,以及typing_extensions或者Python 3.11+内置的inspect模块中相关的类型解析工具。核心思路是先获取目标对象的类型提示,然后判断类型提示是否为Annotated类型,如果是则从中拆分出基础类型和元数据部分。

基础提取示例

下面的代码演示了如何提取函数参数中Annotated类型的元数据:

from typing import Annotated, get_type_hints
from typing_extensions import get_origin, get_args

def get_annotated_metadata(hint):
    # 判断类型提示是否为Annotated类型
    if get_origin(hint) is Annotated:
        # 获取Annotated的所有参数,第一个是基础类型,后面的都是元数据
        args = get_args(hint)
        base_type = args[0]
        metadata = args[1:]
        return base_type, metadata
    return hint, ()

# 定义带Annotated类型参数的函数
def register_user(name: Annotated[str, "用户名", 2, 10], age: Annotated[int, "年龄", 0, 150]):
    pass

# 获取函数的类型提示
hints = get_type_hints(register_user)
for param_name, param_hint in hints.items():
    base_type, metadata = get_annotated_metadata(param_hint)
    print(f"参数名:{param_name}")
    print(f"基础类型:{base_type}")
    print(f"元数据:{metadata}")
    print("-" * 30)

运行上述代码,会输出每个参数的基础类型和对应的元数据信息,通过这种方式我们可以快速拿到Annotated中附加的所有补充内容。

提取类属性中的Annotated元数据

除了函数参数,类的属性也可以使用Annotated类型标注,提取方式和函数参数类似,只是获取类型提示的对象变成了类本身:

from typing import Annotated, get_type_hints
from typing_extensions import get_origin, get_args

class User:
    # 为类属性附加元数据
    username: Annotated[str, "用户名", 6, 20]
    age: Annotated[int, "年龄", 0, 120]

# 获取类的类型提示
hints = get_type_hints(User)
for attr_name, attr_hint in hints.items():
    if get_origin(attr_hint) is Annotated:
        args = get_args(attr_hint)
        base_type = args[0]
        metadata = args[1:]
        print(f"属性名:{attr_name}")
        print(f"基础类型:{base_type}")
        print(f"元数据:{metadata}")

提取元数据的注意事项

  • Python 3.11之前的版本中,get_origin和get_args函数需要从typing_extensions模块导入,Python 3.11及以上版本可以直接从typing模块导入这两个函数。
  • 如果类型提示不是Annotated类型,直接调用get_args可能会得到不符合预期的结果,所以提取前一定要先通过get_origin判断类型是否为Annotated。
  • 元数据的顺序和定义时一致,提取后可以按照定义时的约定来解析不同位置的元数据含义,比如约定第一个元数据是描述信息,第二个是最小值,第三个是最大值。
  • get_type_hints函数默认会解析所有可解析的类型提示,如果遇到无法解析的类型标注可能会抛出异常,使用时可以根据需要添加异常处理逻辑。

实际应用场景示例

我们可以结合提取到的元数据实现简单的参数校验功能,比如校验函数参数的取值是否符合Annotated中定义的规则:

from typing import Annotated, get_type_hints
from typing_extensions import get_origin, get_args

def validate_params(func):
    def wrapper(*args, **kwargs):
        hints = get_type_hints(func)
        # 获取函数的参数名列表
        import inspect
        sig = inspect.signature(func)
        param_names = list(sig.parameters.keys())
        # 校验位置参数
        for i, arg in enumerate(args):
            param_name = param_names[i]
            param_hint = hints.get(param_name)
            if param_hint and get_origin(param_hint) is Annotated:
                base_type, metadata = get_args(param_hint)[0], get_args(param_hint)[1:]
                # 简单校验类型
                if not isinstance(arg, base_type):
                    raise TypeError(f"参数{param_name}类型错误,期望{base_type},实际{type(arg)}")
                # 如果是int类型,校验范围
                if base_type is int and len(metadata) >= 2:
                    min_val, max_val = metadata[0], metadata[1]
                    if not (min_val <= arg <= max_val):
                        raise ValueError(f"参数{param_name}值超出范围,应在{min_val}到{max_val}之间")
        return func(*args, **kwargs)
    return wrapper

@validate_params
def add_user(age: Annotated[int, 0, 120]):
    print(f"添加用户,年龄:{age}")

# 正常调用
add_user(25)
# 调用会抛出异常,因为年龄超出范围
# add_user(130)

通过上述示例可以看到,提取Annotated中的元数据后,我们可以灵活地实现各种扩展功能,让类型提示的价值得到更大程度的发挥。

PythonAnnotated类型提示元数据提取typing修改时间:2026-06-28 00:54:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。