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

如何在运行多文件Python项目时自动打印所有执行的函数名?

无需手动加装饰器的函数调用追踪方案

方案1:使用sys.settrace全局追踪

Python内置的sys.settrace可以设置全局追踪函数,自动监控所有函数调用事件,完全不用修改原有项目代码。

示例代码

在项目入口文件的最顶部插入这段代码:

import sys
import os

# 定义项目根目录,用于过滤第三方库的函数
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

def trace_calls(frame, event, arg):
    # 只处理函数调用事件
    if event == 'call':
        func_name = frame.f_code.co_name
        func_file = frame.f_code.co_filename
        # 过滤掉内置/私有函数,以及第三方库的函数
        if not func_name.startswith('_') and PROJECT_ROOT in func_file:
            rel_path = os.path.relpath(func_file, PROJECT_ROOT)
            print(f"执行函数: {func_name} | 文件: {rel_path}")
    # 返回自身以持续追踪后续调用
    return trace_calls

# 开启全局追踪
sys.settrace(trace_calls)

# 导入并启动你的主程序
import your_main_module
your_main_module.main()

注意点

  • 这个方案会追踪所有层级的函数调用,包括嵌套调用和模块间的函数调用。
  • 通过PROJECT_ROOT过滤,可以只打印你自己项目里的函数,避免第三方库的输出干扰。
  • 如果不需要过滤,直接去掉路径判断的逻辑即可。

方案2:动态包装指定模块的函数

如果只想追踪特定模块的函数,可以用inspect模块遍历模块成员,自动给所有函数加包装:

import inspect
import your_target_module

def trace_wrapper(func):
    def wrapped(*args, **kwargs):
        print(f"执行函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapped

# 遍历模块中的所有函数,自动添加包装
for name, obj in inspect.getmembers(your_target_module, inspect.isfunction):
    setattr(your_target_module, name, trace_wrapper(obj))

# 运行模块主逻辑
your_target_module.main()

扩展

如果要处理多个模块,可以写个递归函数,遍历所有导入的模块进行包装,不过要注意避免重复包装。

方案3:自定义导入钩子批量处理

通过自定义导入钩子,可以在模块加载时自动为其中的函数添加追踪逻辑,适合整个项目的批量处理,无需逐个模块手动操作:

import sys
import types
from functools import wraps

def trace_func(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"执行函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

class TraceImportHook:
    def find_module(self, name, path=None):
        # 只处理你的项目模块,替换成实际的包名前缀
        if name.startswith("your_project_package."):
            return self
        return None

    def load_module(self, name):
        if name in sys.modules:
            return sys.modules[name]
        # 导入原始模块
        module = __import__(name)
        sys.modules[name] = module
        # 遍历模块内的所有函数并包装
        for attr_name, attr in module.__dict__.items():
            if isinstance(attr, types.FunctionType):
                setattr(module, attr_name, trace_func(attr))
        return module

# 注册导入钩子,放在所有模块导入前
sys.meta_path.insert(0, TraceImportHook())

# 启动主程序
import your_project_main
your_project_main.main()

说明

  • 这个钩子会拦截指定前缀的模块导入,自动给模块内的所有函数加上追踪逻辑。
  • 把your_project_package.替换成你项目的包名前缀,就能只处理自己的代码。

内容的提问来源于stack exchange,提问作者Niandra Lades

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:30:12