首页
/ CPython inspect 模块完全指南:运行时内省、签名解析与解释器栈探测

CPython inspect 模块完全指南:运行时内省、签名解析与解释器栈探测

2026-09-07 10:34:47作者:董宙帆

inspect 是 CPython 标准库中面向"活对象"(live objects)的元编程核心工具。它围绕模块、类、方法、函数、traceback、帧(frame)与代码对象(code object)提供四类服务:类型与成员检查、源码获取、可调用对象签名解析、以及解释器调用栈探测。读完本文,你将掌握用 inspect 构建调试器、参数校验层、自动化文档生成器与协程调度器等工具所需的全部 API、底层对象模型与源码实现路径。

本文以 CPython 官方库参考 Doc/library/inspect.rst 为骨架,结合纯 Python 实现 Lib/inspect.py(当前版本约 3500 行)与测试套件 Lib/test/test_inspect/ 展开,逐项说明函数语义、可作用对象、异常约定与版本演化。

一、模块概览:四种服务与使用入口

模块入口文档(Doc/library/inspect.rst)将该模块能力划分为四类:

  1. 类型检查(type checking):对对象属于模块、类、方法、函数等哪种类型给出布尔判定;
  2. 获取源码(getting source code):取回某对象的源文件、源行、注释与整理后的 docstring;
  3. 检查类与函数(inspecting classes and functions):解析参数列表、方法解析顺序(MRO)、闭包变量等;
  4. 检查解释器栈(examining the interpreter stack):遍历帧对象与 traceback,还原调用现场。

inspect 的模块级 docstring(Lib/inspect.py 顶部)自述其设计目标:"封装内部特殊属性(co_、tb_* 等)为更友好的接口"*。也就是说,inspect 本质上是把散落在各对象上的双下划线/单下划线属性(__doc____code__f_backtb_next……)包装成一组语义化函数。

使用 getmembers 获取对象全部成员、用 is* 系列函数作为筛选谓词,是该模块最经典的使用范式。测试目录 Lib/test/test_inspect/ 中的 inspect_fodder.pyinspect_fodder2.py 等"喂料"模块定义了大量用于验证的类层级,是理解各 API 边界的最佳活例。

二、类型与成员:getmembers 与 is* 谓词

2.1 成员枚举

  • getmembers(object[, predicate]):返回对象所有成员,形如 (name, value) 的列表并按名字排序。可选谓词以每个成员的 value 为参数调用,只保留返回真值的成员。注意:当参数是类时,只有被元类自定义 __dir__ 列出的元类属性才会被返回。
  • getmembers_static(object[, predicate])(3.11+):与 getmembers 类似,但不触发描述符协议、__getattr____getattribute__ 的动态查找。它可能取不到 getmembers 能取到的动态属性(如实例运行时新加属性),也可能"发现" getmembers 取不到的东西(如会抛 AttributeError 的描述符),某些场景下返回描述符对象而非实例成员。

从实现看(Lib/inspect.py),二者共享私有函数 _getmembers(object, predicate, getattr),差别仅在第三个参数分别传入 getattrgetattr_static——一个函数就说明了"静态成员遍历"的本质:只是换掉取值函数。

2.2 各类型对象的特殊属性总表

getmembers 的返回值能覆盖哪些"期望属性",取决于对象类型。下表整理自官方文档(原表见 Doc/library/inspect.rst),模块属性另见 importlib 相关文档:

类型 属性 说明
class __doc__ 文档字符串
__name__ 定义时使用的类名
__qualname__ 限定名(含所在类/模块路径)
__module__ 定义所在模块名
__type_params__ 泛型类的类型参数元组(PEP 695)
method(绑定方法) __doc__ / __name__ / __qualname__ / __module__ 同上语义
__func__ 承载方法实现的函数对象
__self__ 方法绑定到的实例,未绑定时为 None
function __doc__ / __name__ / __qualname__ / __module__ 同上语义
__code__ 含编译后字节码的代码对象
__defaults__ 位置/关键字参数的默认值元组
__kwdefaults__ 仅限关键字参数默认值的映射
__globals__ 定义该函数的全局命名空间
__builtins__ builtins 命名空间(3.10+)
__annotations__ 参数名到注解的映射,"return" 键保留给返回注解
__type_params__ 泛型函数的类型参数元组
traceback tb_frame / tb_lasti / tb_lineno / tb_next 本层帧对象、最后尝试指令的字节码下标、当前源码行号、被本层调用的内层 traceback
frame f_back 外层帧(调用者)
f_builtins / f_globals / f_locals 本帧可见的 builtins / 全局 / 局部命名空间
f_code 本帧正在执行的代码对象
f_lasti / f_lineno 最后尝试指令下标 / 当前源码行号
f_generator 拥有该帧的生成器或协程对象;普通函数帧为 None(3.14+)
f_trace / f_trace_lines / f_trace_opcodes 本帧跟踪函数及是否逐行/逐操作码触发跟踪事件
clear() 清除对局部变量的全部引用
code co_argcount / co_posonlyargcount / co_kwonlyargcount 参数个数(不含 keyword-only、***)等细分计数
co_code 原始编译字节码字符串
co_cellvars / co_freevars 单元变量(被外层作用域引用)与自由变量(经闭包引用)
co_consts / co_names / co_varnames / co_nlocals / co_stacksize 常量、非局部名字、局部变量、栈空间等元数据
co_filename / co_firstlineno / co_name / co_qualname 文件名、首行号、名字、限定名
co_flags CO_* 标志位图(见后文专节)
co_lines() / co_positions() 产出字节码区间 / 每个指令源码位置
replace() 返回替换字段后的代码对象副本
generator __name__ / __qualname__ 名字与限定名
gi_frame / gi_code 帧与代码对象
gi_running / gi_suspended 是否运行中 / 是否挂起于 yield(后者 3.11+)
gi_yieldfrom yield from 迭代的对象,无则为 None
gi_state 状态之一(3.15+,详见状态节)
async generator ag_await / ag_frame / ag_code 被 await 对象(可为 None)、帧、代码
ag_running / ag_suspended 运行/挂起标志
ag_state AGEN_* 状态(3.15+)
coroutine cr_await / cr_frame / cr_code 被 await 对象、帧、代码
cr_running / cr_suspended 运行/挂起标志
cr_origin 协程创建点(配合 sys.set_coroutine_origin_tracking_depth,3.7+)
cr_state CORO_* 状态(3.15+)
builtin __doc__ / __name__ / __qualname__ / __self__ 内置函数/方法的文档、原名、限定名、绑定实例

关键版本变更:3.5 起生成器 __name__ 取自函数名且可修改,新增 gi_yieldfrom;3.7 新增 cr_origin;3.10 函数新增 __builtins__;3.11/3.12 分别为生成器与协程增加 gi_suspended/cr_suspended,异步生成器则于 3.12 增加 ag_suspended;3.14 帧增加 f_generator;3.15 为三类协程对象统一增加 *_state

2.3 is* 谓词系列

这些谓词最主要的用途正是充当 getmembers 的第二参数:

  • ismoduleisclassispackage(3.14+):模块 / 类(内置类与 Python 类均可,对泛型别名如 list[int] 返回 False)/ 包判断;
  • ismethod:Python 编写的绑定方法。文档用 Greeter 示例区分绑定方法与普通函数——通过实例访问返回绑定方法(ismethod(...) is Trueisfunction(...) is False),通过类访问返回函数本身(结论相反);
  • isfunction:Python 函数,含 lambda
  • isgeneratorfunctionisgenerator:生成器函数 / 生成器对象。对生成器函数派生的绑定方法同样返回真;3.8 起支持 functools.partial 包裹,3.13 起支持 functools.partialmethod 包裹;
  • iscoroutinefunction:以 async def 定义的协程函数,也接受 partial 包裹、partialmethod 包裹(3.13+)及被 markcoroutinefunction 标记的同步函数(3.12+)。注意该函数不保证对"返回协程的同步函数"返回真,这正是引入标记机制的原因;
  • markcoroutinefunction(func)(3.12+):装饰器,为无法被自动识别的"返回协程的同步函数"打标。官方建议优先用 async def;其次可调用后以 iscoroutine 验证返回值;
  • iscoroutineasync def 函数创建的协程对象;
  • isawaitable:可用于 await 表达式的对象,能区分基于生成器的协程与普通生成器——配合 types.coroutine 装饰器的示例:普通 gen() 不可 await,gen_coro() 可 await;
  • isasyncgenfunctionisasyncgen:异步生成器函数与迭代器(3.6+),同样兼容 partial/partialmethod 包裹;
  • istracebackisframeiscode:traceback / 帧 / 代码对象;
  • isbuiltin:内置函数或绑定的内置方法;
  • ismethodwrapper(3.11+):types.MethodWrapperType 实例,如 __str____eq____repr__
  • isroutine:用户定义或内置的函数/方法;
  • isabstract:抽象基类(ABC);
  • ismethoddescriptor:方法描述符(对同时满足 isclass/ismethod/isfunction 的对象返回 False)。例如 int.__add__ 即通过该测试——有 __get__ 而无 __set__/__delete__。3.13 修正了一处误判:仅有 __get__+__delete__ 而无 __set__ 的对象属于数据描述符而非方法描述符;
  • isdatadescriptor:数据描述符(恒具 __set____delete__),典型如 property、getset 与 member 描述符。3.8 放宽为"只要有 __set__ 即算";
  • isgetsetdescriptorismemberdescriptor:分别对应扩展模块中以 PyGetSetDefPyMemberDef 结构定义的属性(见 CPython C-API),无此类类型的 Python 实现恒为 False

分类辅助还有 classify_class_attrs(cls),返回 Attribute(name, kind, defining_class, object) 四元组,把成员分成 'class method''static method''property''method''data' 等类别(实现在 Lib/inspect.py)。

2.4 其它常用辅助

  • getmodulename(path):由文件路径猜模块名(剥去扩展名)。扩展名必须命中 importlib.machinery.all_suffixes() 才返回名字,否则返回 None;对包目录路径同样返回 None。3.3 起直接基于 importlib 实现。

三、获取源码:getsource 家族与文档字符串整理

  • getdoc(object, *, inherit_class_doc=True, fallback_to_class_doc=True, dedent=True):返回经 cleandoc 整理的文档字符串。对象无 docstring 时按序回退:类是且 inherit_class_doc 为真 → 沿继承层级取;方法/property/描述符 → 沿继承层级取;否则若 fallback_to_class_doc 为真 → 取对象的类。无效或缺失返回 None。3.5 起 docstring 可被继承;3.15 起新增两个开关参数并支持 functools.cached_property 上的 docstring 继承;dedent 为新增参数(见下文);
  • cleandoc(doc, *, dedent=True):清洗缩进的 docstring。规则:首行去除全部前导空白;后续各行统一去除可均匀去掉的缩进(dedent=False 时跳过);剥除首尾空行;制表符展开为空格。由于 Python 3.13 起编译器会自行去掉 docstring 缩进,dedent 实际只影响非源码 docstring(如 Argument Clinic 生成、缩进有意义的文本);
  • getcomments(object):返回紧邻对象源码之前(类/函数/方法)或源文件顶部(模块)的注释,多行合并为一个字符串;对象无源码(C 扩展或交互式 shell 定义)返回 None
  • getfile(object):对象定义所在(文本或二进制)文件名。取不到源码抛 OSError;对内置模块/类/函数抛 TypeError
  • getsourcefile(object):Python 源文件名;无法定位返回 None;取不到源码抛 OSError,内置对象抛 TypeError
  • getmodule(object):猜测对象所在模块,失败返回 None
  • getsource(object)getsourcelines(object):前者把对象源码作为单个字符串返回,后者返回 (行列表, 起始行号)。二者可接受模块、类、方法、函数、traceback、帧、代码对象;C 内置对象抛 TypeError(3.3 起 IOError 被并入 OSError)。

四、可调用对象签名:Signature / Parameter / BoundArguments

Signature 体系(PEP 362 的实现)自 3.3 引入,是 inspect 中工程价值最高、被第三方框架引用最多的部分。

4.1 获取签名:signature()

signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False, annotation_format=Format.VALUE) 返回 Signature 对象,接受从普通函数、类到 functools.partial 的广泛可调用对象。文档示例:

>>> from inspect import signature
>>> def foo(a, *, b: int, **kwargs):
...     pass
>>> sig = signature(foo)
>>> str(sig)
'(a, *, b: int, **kwargs)'
>>> str(sig.parameters['b'])
'b: int'
>>> sig.parameters['b'].annotation
<class 'int'>

要点:

  • 自动反字符串化注解:若注解是字符串(如使用了 from __future__ import annotations),signature 会借助 annotationlib.get_annotations 尝试求值还原,globals/locals/eval_str 透传给该函数;annotation_format(3.14+)可传 annotationlib.Format.STRING 等以控制返回注解形态;
  • 错误约定:无法提供签名抛 ValueError;不支持的对象类型抛 TypeError;字符串化注解且 eval_str 非假时,反序列化 eval() 可能抛出任意异常;
  • 斜杠语义:签名中的 / 表示其前参数为 positional-only(详见 FAQ 关于仅限位置参数的说明,涉及 CPython 3.8+ 的 / 语法);
  • follow_wrapped(3.5+)默认跟踪 __wrapped__ 链解开装饰器;传 False 只看对象自身;
  • 兼容性边界:部分 C 实现的 builtin 不提供参数元数据,无法被内省(如某些 CPython 内置函数);
  • 实现细节:若对象定义了 __signature__ 属性,可能以其构建签名——确切语义属实现细节。从源码看,顶层 signature() 直接委托 Signature.from_callable(...)Lib/inspect.py),真正的逻辑分布在 _signature_from_functionLib/inspect.py)与 _signature_from_callableLib/inspect.py)两个私有函数中,后者负责 unwrap、查询 __signature__、区分内置函数与各类对象的分派。

4.2 Signature 类

Signature(parameters=None, *, return_annotation=Signature.empty) 表示函数签名及返回注解。构造时会校验:无重名参数、顺序合法(positional-only 在前,带默认值参数排在无默认值之后)。Signature 对象不可变,修改副本用 replacecopy.replace;3.5 起可 pickle、可哈希。源码用 __slots__ = ('_return_annotation', '_parameters') 保证不可变与紧凑(Lib/inspect.py)。

  • Signature.empty:类级哨兵,表示无返回注解;
  • Signature.parameters:参数名到 Parameter 的有序映射,含 keyword-only 参数,严格按定义顺序排列(3.7 起语言层显式保证 keyword-only 顺序);
  • Signature.return_annotation:返回注解,无则 empty
  • Signature.bind(*args, **kwargs):把实参映射到形参,匹配成功返回 BoundArguments,否则抛 TypeError
  • Signature.bind_partial(*args, **kwargs):同 bind 但允许缺省必填参数(模拟 functools.partial);
  • Signature.replace(*[, parameters][, return_annotation]):基于原对象构造新签名,覆盖指定字段;用 empty 移除返回注解。文档示例用 sig.replace(return_annotation="new return anno") 得到 "(a, b) -> 'new return anno'"
  • Signature.format(*, max_width=None, quote_annotation_strings=True)(3.13+):字符串化。传 max_width 时尽量折行,超过则每个参数独占一行;quote_annotation_strings=False 可去掉字符串注解的引号(适配 Format.STRING 或 future annotations 场景)。3.14 起增加 unquote_annotations 兼容参数;
  • Signature.from_callable(obj, ...)(类方法,3.5+):与 signature() 行为一致但允许子类化 Signature(示例 MySignature.from_callable(sum) 返回 MySignature 实例),3.10 起同样接受 globals/locals/eval_str。

4.3 Parameter 类

Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty) 不可变(修改用 replace/copy.replace),3.5 起可 pickle、可哈希。

  • Parameter.empty:哨兵,表示无默认值/无注解;
  • Parameter.name:参数名字符串,必须是合法 Python 标识符。实现细节:CPython 为推导式/生成器表达式的代码对象生成形如 .0 的隐式参数名,3.6 起本模块以 implicit0 之类名字暴露;
  • Parameter.default / Parameter.annotation:默认值 / 注解,无则 empty
  • Parameter.kind:参数绑定方式枚举,按序支持比较:
kind 取值 含义
POSITIONAL_ONLY 必须以位置实参提供(定义中 / 之前的参数)
POSITIONAL_OR_KEYWORD 位置或关键字均可(Python 函数默认行为)
VAR_POSITIONAL 未绑定到其它形参的位置实参元组,即 *args
KEYWORD_ONLY 必须以关键字提供(**args 之后)
VAR_KEYWORD 未绑定的关键字实参字典,即 **kwargs

Parameter.kind.description(3.8+)返回可读描述,示例输出 positional or keywordkeyword-only 等。文档中的过滤示例是经典写法:遍历 sig.parameters.values(),命中 kind == KEYWORD_ONLY and default is empty 即打印无默认值的仅关键字参数。Parameter.replace 支持按需覆盖 name/kind/default/annotation,用 empty 移除默认值或注解。

4.4 BoundArguments 类

Signature.bind/bind_partial 的返回结果,承载"实参→形参"映射:

  • arguments:参数名到实参值的可变映射,只含显式绑定项(依赖默认值的参数被跳过),改动会同步反映到 args/kwargs。3.9 起类型为 dict(此前为 OrderedDict);
  • args:位置实参值元组,由 arguments 动态计算;
  • kwargs:关键字实参字典,凡可位置传递的实参都进 args 而非 kwargs
  • signature:父 Signature 引用;
  • apply_defaults()(3.5+):补上缺失参数的默认值——*args 补空元组、**kwargs 补空字典。示例:
>>> def foo(a, b='ham', *args): pass
>>> ba = inspect.signature(foo).bind('spam')
>>> ba.apply_defaults()
>>> ba.arguments
{'a': 'spam', 'b': 'ham', 'args': ()}

args/kwargs 可直接解包调用目标函数:

def test(a, *, b):
    ...
sig = signature(test)
ba = sig.bind(10, b=20)
test(*ba.args, **ba.kwargs)

getfullargspec 在文档中明示:"signature 与 Signature Object 是推荐的可调用对象内省 API,本函数主要为兼容 Python 2 inspect 模块 API 保留"(详见下文)。

五、类与函数内省辅助

  • getclasstree(classes, unique=False):把类列表排成嵌套层级。嵌套列表表示其前一个类的派生类;每个条目是 (类, 基类元组) 二元组。unique=True 时每个类只出现一次,否则多重继承的类及其后代可重复出现;
  • getmro(cls):返回含 cls 在内的基类元组,按方法解析顺序排列且不重复(cls 通常为第一项,除非使用特殊元类);
  • getfullargspec(func, *, annotation_format=Format.VALUE):返回具名元组 FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)。其中 defaults 是末尾 n 个位置参数的默认值元组,无默认值时是 Noneannotations 字典的 "return" 键保留给返回注解。历史沿革:3.4 起基于 signature 实现,但忽略 __wrapped__、对绑定方法会包含已绑定的首参;3.5 曾被标记弃用,3.6 撤销弃用以支持单源 Python 2/3 代码迁移;3.15 新增 annotation_format。警告:默认 VALUE 格式下构造某些 argspec 可能抛异常;
  • getargvalues(frame):返回 ArgInfo(args, varargs, keywords, locals)。其中 args 为参数名列表,varargs/keywords*/** 参数名或 Nonelocals 为该帧的局部字典。配套的 formatargvalues(...) 把四个值格式化为漂亮的参数说明(format* 形参是可选的自定义格式化回调)。二者都曾在 3.5 被误标弃用(文档特别澄清);
  • getcallargs(func, /, *args, **kwds):把实参绑定到形参名,如同真正调用(含 self 绑定),返回名字→值字典;调用不合法时抛出与 func(*args, **kwds) 相同类型与相近信息的异常。3.5 起弃用,改用 Signature.bind/bind_partial
  • getclosurevars(func):返回 ClosureVars(nonlocals, globals, builtins, unbound)nonlocals 映射词法闭包变量,globals 映射模块全局,builtins 映射函数体内可见的内置名,unbound 是当前模块全局与内置下都无法解析的名字集合。对非 Python 函数/方法抛 TypeError(3.3+);
  • unwrap(func, *, stop=None)(3.4+):沿 __wrapped__ 链取最内层对象。stop 是接收链上对象、返回真即提前终止的回调——signature 内部正是用它来在遇到带 __signature__ 的对象时停止解包;遇环抛 ValueError
  • get_annotations(obj, *, globals=None, locals=None, eval_str=False, format=annotationlib.Format.VALUE):3.10 引入,3.14 起成为 annotationlib.get_annotations 的别名(旧调用方式仍可用)。安全警告:该函数可能执行注解中蕴含的任意代码,相关风险详见 annotationlib 文档的安全专节。

六、解释器栈探测

本节函数围绕 frame 对象构建调用栈视图,返回的 FrameInfo 记录对象。

6.1 记录类型

  • FrameInfo:字段 frame(帧对象)、filenamelineno(当前执行行号)、function(执行中的函数名)、code_context(源码上下文行列表)、index(当前行在 code_context 中的下标)、positionsdis.Positions,含起始/结束行列)。3.5 为具名元组;3.11 改为类实例但向后兼容元组式操作;
  • Tracebackgetframeinfo 的返回类型,3.11 起):字段与 FrameInfo 相同的 traceback 视角记录(filename/lineno/function/code_context/index/positions)。

引用循环警告:保留帧对象会造成引用环,使可达对象生命周期显著拉长(即便启用循环 GC)。建议用 finally: del frame 确定性释放,或调用 frame.clear() 打破循环:

def handle_stackframe_without_leak():
    frame = inspect.currentframe()
    try:
        # do something with the frame
    finally:
        del frame

各函数普遍支持可选的 context 参数,指定以当前行为中心返回的上下文行数。

6.2 栈与帧 API

  • getframeinfo(frame, context=1):取帧或 traceback 的信息,返回 Traceback 对象(3.11 前为具名元组);
  • getouterframes(frame, context=1):返回 frame 及其全部外层帧的 FrameInfo 列表——代表产生 frame 的调用链,首项即 frame 本身,末项为最外层调用;
  • getinnerframes(traceback, context=1):返回 traceback 帧及其内层帧列表——代表 frame 引发的后续调用,首项为 traceback,末项为异常抛出点;
  • currentframe():返回调用者的栈帧。实现细节:依赖解释器的 Python 栈帧支持,无帧支持的实现返回 None
  • stack(context=1):调用者调用栈的 FrameInfo 列表,首项是调用者,末项是最外层;
  • trace(context=1):当前帧到正在处理异常抛出帧之间栈的 FrameInfo 列表。

这些函数在 Lib/inspect.py 中围绕帧遍历实现,getframeinfo 从第 1602 行起、currentframe 从第 1688 行起,均有对应单元测试覆盖(见 Lib/test/test_inspect/)。

七、静态属性获取:getattr_static

getattr/hasattr 在取属性时会执行代码:property 等描述符被调用,__getattr__/__getattribute__ 可能触发。文档工具这类"被动内省"场景需要 getattr_static(obj, attr[, default])(3.2+)——签名类似 getattr,但取属性时不触发描述符协议、__getattr____getattribute__

局限性(文档明示):可能取不到动态创建属性、可能取到 getattr 取不到的(如抛 AttributeError 的描述符);__dict__ 被同名成员(如 property)遮蔽时无法找到实例成员。

getattr_static 不解析 slot 描述符与 C 实现的 getset 描述符,返回的是描述符对象本身。文档给出解析内置描述符类型的模板:

class _foo:
    __slots__ = ['foo']

slot_descriptor = type(_foo.foo)
getset_descriptor = type(type(open(__file__)).name)
wrapper_descriptor = type(str.__dict__['__add__'])
descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)

result = getattr_static(some_object, 'foo')
if type(result) in descriptor_types:
    try:
        result = result.__get__()
    except AttributeError:
        pass  # 描述符可能以 AttributeError 表示无底层值

注意:对任意 getset 描述符调用 __get__ 可能触发代码执行。实现上,getmembers_static 正复用了 getattr_static(见 Lib/inspect.py)。

八、生成器、协程与异步生成器状态查询

实现协程调度器等高级用法时,需要判断生成器处于"待执行、运行中、挂起还是已终止"。状态常量定义于 Lib/inspect.py

  • getgeneratorstate(generator)(3.2+):状态为 GEN_CREATED(等待开始)、GEN_RUNNING(解释器正在执行)、GEN_SUSPENDED(挂起于 yield 表达式)、GEN_CLOSED(执行完毕);
  • getcoroutinestate(coroutine)(3.5+):CORO_CREATED / CORO_RUNNING / CORO_SUSPENDED(挂起于 await)/ CORO_CLOSED。本为 async def 协程设计,但接受任何具 cr_running/cr_frame 属性的协程样对象;
  • getasyncgenstate(agen)(3.12+):AGEN_CREATED / AGEN_RUNNING / AGEN_SUSPENDED / AGEN_CLOSED,接受具 ag_running/ag_frame 的异步生成器样对象。

还有查询内部活局部变量的函数,多用于测试以确保内部状态更新符合预期:

  • getgeneratorlocals(generator)(3.3+):生成器活局部变量名→值映射,等价于在生成器体内调用 locals()(含同样注意点)。无关联帧时返回空字典;非 Python 生成器抛 TypeError。实现依赖生成器暴露可内省的 Python 栈帧,不支持时恒返回空字典;
  • getcoroutinelocals(coroutine)(3.5+)、getasyncgenlocals(agen)(3.12+):同前者,分别面向协程与异步生成器。

九、代码对象的 CO_* 位标志

code.co_flags 是位图。各标志语义(均为 CPython 特有,其它实现可能缺失,且属于实现细节、未来可能变动——官方强烈建议优先使用 inspect 的公开 API):

标志 含义
CO_OPTIMIZED 代码已优化,使用快速局部变量
CO_NEWLOCALS 置位时执行该代码会为帧 f_locals 新建字典
CO_VARARGS *args 样可变位置参数
CO_VARKEYWORDS **kwargs 样可变关键字参数
CO_NESTED 代码对象为嵌套函数
CO_GENERATOR 生成器函数,执行返回生成器对象
CO_COROUTINE 协程函数,执行返回协程对象(PEP 492,3.5+)
CO_ITERABLE_COROUTINE 把生成器转为基于生成器的协程,可 await 且可 yield from 协程(PEP 492,3.5+)
CO_ASYNC_GENERATOR 异步生成器函数,执行返回异步生成器对象(PEP 525,3.6+)
CO_HAS_DOCSTRING 源码带 docstring,且其为 co_consts 首项(3.14+)
CO_METHOD 在类作用域内定义的函数(3.14+)

十、缓冲区标志 BufferFlags

BufferFlagsenum.IntFlag(定义于 Lib/inspect.py),表示传给实现了 buffer 协议对象 __buffer__ 方法的标志,语义详见 buffer 请求类型文档。成员包括:SIMPLEWRITABLEFORMATNDSTRIDESC_CONTIGUOUSF_CONTIGUOUSANY_CONTIGUOUSINDIRECTCONTIGCONTIG_ROSTRIDEDSTRIDED_RORECORDSRECORDS_ROFULLFULL_ROREADWRITE。从源码可见其组合关系:STRIDES = 0x10 | NDRECORDS_RO = STRIDES | FORMATFULL = INDIRECT | WRITABLE | FORMAT,可对照 Python/C API 层(Include/pybuffer.hPyBUF_*)理解一一对应关系(3.12+)。

十一、命令行内省:python -m inspect

inspect 自带基础命令行能力(入口 _main()Lib/inspect.py):

python -m inspect 模块名            # 打印模块源码
python -m inspect 模块:类.方法       # 打印模块内对象的源码
python -m inspect --details 目标    # 打印对象信息而非源码

用法细节:默认接受模块名并打印其源码;用冒号后跟目标对象的限定名可定位到模块内的类或函数。--details 选项打印对象信息而非源码。3.15 起 --details 对无可用源码的模块也能做基础内省、指出模块是否被冻结(frozen),并提示给定目标引用是否为对象规范名之外的别名。

CLI 实现要点(来自源码注释与逻辑):解析 module:qualname 语法后 importlib.import_module 再逐段 getattrLib/inspect.py);_get_details_for_cli 会通过 getmodule 判定目标是否定义于别的模块,若用户给出的名字只是别名/再导出名,则报告真正定义模块并以 alias 字段标注(Lib/inspect.py);无源码的 builtin 模块与普通模块分别给出对应错误信息。

十二、测试验证与深入研读指引

inspect 拥有独立成目录的测试套件 Lib/test/test_inspect/,其中 inspect_fodder.pyStupidGitMalodorousPervertFesteringGob 的多重继承链)、inspect_fodder2.py(覆盖 TypedDict、NamedTuple、Enum/IntFlag/Flag、dataclass 等泛型与特殊类)、inspect_fodder3.py(docstring 继承场景)为各 API 提供了可直接阅读的"标的物";另有 inspect_stock_annotations.pyinspect_stringized_annotations.pyinspect_stringized_annotations_pep695.py 等专门验证注解反字符串化与 PEP 695 类型参数行为。阅读 Lib/test/test_inspect/ 中对应主测试文件,是理解 signature() 在不同类对象(含 NamedTuple、泛型类、枚举)上的边界行为的最高效途径。

小结

inspect 的价值在于把 CPython 对象模型中的内部属性封装为稳定的公开 API:is* 谓词 + getmembers 解决"对象里有什么、是什么";getsource/getdoc 解决"对象源码与文档在哪";Signature 体系解决"怎么调用它"(参数绑定、默认值、注解、位置限制);栈探测函数解决"当前执行到哪里"。在框架层做参数校验、命令行工具生成帮助、IDE 补全与调试器实现时,inspect 往往是被依赖最深的标准库模块之一。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388