python中`__annotations__` 和 `inspect` 模块区别??

__annotations__ 和 inspect 模块在 Python 中都与类型注解(type annotations)有关,但它们的作用范围和使用方式有显著区别。下面我们从多个维度来详细对比这两者。


🧩 一、__annotations__ 是什么?

__annotations__ 是 Python 中类、函数或模块对象的一个内置属性,用于存储类型注解。它是一个字典,其中键是变量名或参数名,值是类型对象。

示例:

python 复制代码
def func(a: int, b: str) -> bool:
    pass
print(func.__annotations__)
# 输出:{'a': <class 'int'>, 'b': <class 'str'>, 'return': <class 'bool'>}

对于类来说,__annotations__ 只包含类级别的变量注解,不包含方法参数或返回值的注解:

python 复制代码
class MyClass:
    x: int
    y: str = "hello"
    def method(self, a: float) -> bool:
        return True
print(MyClass.__annotations__)
# 输出:{'x': <class 'int'>, 'y': <class 'str'>}

🔍 二、inspect 模块是什么?

inspect 是 Python 标准库中的一个模块,用于动态检查对象的结构,包括类、函数、方法、模块等。它不仅可以获取类型注解,还能获取参数列表、默认值、源码、文档字符串等更丰富的信息。

常用功能:

  • inspect.signature():获取函数/方法的签名(包括参数名、默认值、类型注解等)
  • inspect.getmembers():列出对象的所有成员
  • inspect.isfunction() / inspect.ismethod():判断对象是否为函数或方法
  • inspect.getsource():获取源代码

示例:

python 复制代码
import inspect
def func(a: int, b: str = "hi") -> bool:
    return True
sig = inspect.signature(func)
print(sig)
# 输出:(a: int, b: str = 'hi') -> bool
for param in sig.parameters.values():
    print(param.name, ":", param.annotation)
# 输出:
# a : <class 'int'>
# b : <class 'str'>

🆚 三、核心区别对比

项目 __annotations__ inspect 模块
作用范围 只获取类型注解 可获取注解、参数、默认值、源码、文档等
内容丰富度 仅字典结构,仅包含注解 结构化对象,包含完整的函数/方法签名信息
适用对象 类、函数、模块 函数、方法、类、模块、帧对象等
获取方式 直接访问 obj.__annotations__ 通过 inspect.signature() 等函数获取
能否获取默认值 ❌ 不能 ✅ 可以
能否获取参数顺序 ❌ 不能 ✅ 可以
能否获取方法签名 ❌ 只能获取类变量注解 ✅ 可以,包括参数名、类型、默认值、返回值

🧪 四、实际使用场景建议

使用 __annotations__ 的场景:

  • 你只需要类型注解,不关心参数顺序、默认值等。
  • 代码简单,不想引入额外的模块。
  • 在元类或装饰器中快速检查类变量类型。

使用 inspect 的场景:

  • 你需要完整的函数/方法签名,包括参数名、顺序、默认值、类型注解等。
  • 需要动态生成文档、进行参数校验、实现依赖注入等高级功能。
  • 需要分析对象结构,如列出所有方法、属性等。

✅ 五、总结

对比项 推荐使用
只需要类型注解 __annotations__
需要完整方法签名 inspect.signature()
需要参数顺序/默认值 inspect
需要动态分析对象 inspect
如果你只是想查看类型注解,__annotations__ 足够轻量;但如果你需要更深入的分析(如参数顺序、默认值、方法签名等),inspect 是更强大的选择。
相关推荐
郑州光合科技余经理22 分钟前
同城商城源码:商品库和订单库怎么随包交付
android·java·开发语言·后端·uni-app·php·ai编程
\光辉岁月/23 分钟前
4.String类
java·面向对象·stringbuilder·string·stringbuffer·字符串类
iCxhust34 分钟前
模型:500kW飞轮 10kV输电线路 油田抽油机 同时考虑无功补偿 统计:全年节电量 结果56万度电
前端·css·css3·电力·飞轮
MoRanzhi120340 分钟前
第3篇 · 使用 PyQt5 实现 2048 桌面版游戏:MVC 架构与撤销和重做
python·mvc·pyqt5·桌面应用开发·gui开发·2048游戏·撤销与重做
蚰蜒螟44 分钟前
从 Java SocketChannel 到 TCP 挥手:一次 close() 的完整调用链与引用计数解析
java·python·tcp/ip
damoluomu1 小时前
国产 Java CMS 的协议和坑,讲清楚
java·开发语言
志尊宝1 小时前
AI原生前端开发(011):Chrome 148+内置Gemini Nano入门
前端·chrome·ai-native
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 黑名单:分页查询黑名单
java·开发语言·交友
Smoothcloud润云1 小时前
GPU算力平台跑知识库问答,模型回答总跑偏?先排查检索链路
人工智能·python·深度学习·gpu算力·gpu