You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python inspect模块获取调用方法的直接被调用方信息?

在Python中记录方法内部的直接被调用方信息

首先明确:可以通过inspect模块结合其他工具实现,但inspect.getinnerframes()并非直接解决方案——它仅用于解析已捕获的traceback对象(如异常栈),无法在正常执行流程中动态追踪当前方法调用的内部函数。

为什么inspect.getinnerframes()不适用

inspect.getinnerframes()需要传入一个traceback实例(通常来自try-except块中的exc_info()),作用是提取异常发生时调用栈的内层帧信息。它无法主动追踪正常执行过程中方法内部发起的函数调用,因此不符合你动态记录直接被调用方的需求。

可行的实现方案

方案1:使用sys.settrace()动态追踪调用

通过设置全局跟踪函数,可以在函数调用事件触发时,捕获目标方法内部发起的所有直接调用。这种方式能动态记录执行过程中的调用关系,无侵入性(无需修改被调用函数)。

示例代码:

import sys
import inspect

def trace_inner_calls(frame, event, arg):
    # 仅处理函数调用事件
    if event != 'call':
        return trace_inner_calls
    
    # 获取调用方的帧信息
    caller_frame = frame.f_back
    # 过滤出目标方法内部的调用(这里假设目标方法名为target_method)
    if caller_frame and caller_frame.f_code.co_name == 'target_method':
        called_func = frame.f_code.co_name
        # 可扩展记录更多信息,如被调用函数的模块、参数等
        print(f"直接被调用方: {called_func}")
    
    return trace_inner_calls

# 模拟被调用方函数
def func_a():
    pass

def func_b():
    pass

# 目标方法
def target_method():
    # 启用跟踪
    sys.settrace(trace_inner_calls)
    # 内部调用的函数
    func_a()
    func_b()
    # 关闭跟踪,避免影响其他代码
    sys.settrace(None)

# 执行测试
target_method()

方案2:静态解析方法的代码对象

如果不需要动态追踪运行时的调用(比如仅需分析代码中显式的函数调用),可以通过inspect.getsource()或inspect.getcode()获取目标方法的代码,再解析其中的函数调用语句。

示例代码:

import inspect
import ast

def get_static_called_funcs(target_func):
    # 获取目标方法的源代码
    source = inspect.getsource(target_func)
    # 解析为AST树
    tree = ast.parse(source)
    called_funcs = []
    
    # 遍历AST节点,查找函数调用
    for node in ast.walk(tree):
        if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
            called_funcs.append(node.func.id)
    
    return called_funcs

# 测试
def target_method():
    func_a()
    func_b()

print(f"静态解析的直接被调用方: {get_static_called_funcs(target_method)}")

注意:这种方式只能捕获显式的静态调用,无法识别动态生成的调用(如通过eval()、字符串转函数的调用)。

方案3:在被调用方中记录调用方

如果允许修改被调用函数的代码,可以在每个被调用函数内部,通过inspect.currentframe().f_back获取调用方的信息并记录。但这种方式侵入性强,仅适用于可控的函数集合。

示例代码:

import inspect

def func_a():
    caller_frame = inspect.currentframe().f_back
    print(f"func_a 被 {caller_frame.f_code.co_name} 调用")

def target_method():
    func_a()

target_method()

总结

  • inspect.getinnerframes()仅适用于异常栈分析,无法满足动态记录正常执行流程中调用关系的需求;
  • 动态追踪优先选择sys.settrace()方案,能无侵入地记录运行时的直接被调用方;
  • 静态解析适合仅需分析代码结构的场景,无需运行程序。

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:41:03