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

Python中如何在不冗余代码的情况下记录函数每一行执行日志?

解决方法

下面提供几种无需手动逐行添加日志的方案,既能记录代码执行路径,又不会让代码冗余:

方案1:自定义代码追踪装饰器

利用Python的sys.settrace机制,写一个装饰器自动记录函数内每一行执行的代码内容,无需修改原函数的业务逻辑:

import sys
import logging
from inspect import getsource

logger = logging.getLogger(__name__)

def trace_execution(func):
    def code_tracer(frame, event, arg):
        if event == 'line':
            # 获取当前执行行的代码文本
            try:
                line_content = getsource(frame.f_code).splitlines()[frame.f_lineno - 1].strip()
                logger.info(f"Executing line: {line_content}")
            except (OSError, IndexError):
                # 处理无法获取源码的情况,记录行号和函数名
                logger.info(f"Executing in {frame.f_code.co_name}, line {frame.f_lineno}")
        return code_tracer

    def wrapper(*args, **kwargs):
        # 保存原追踪函数,执行后恢复全局状态
        original_tracer = sys.gettrace()
        sys.settrace(code_tracer)
        try:
            return func(*args, **kwargs)
        finally:
            sys.settrace(original_tracer)
    return wrapper

# 给目标函数添加装饰器即可
@trace_execution
def my_annoying_function(self):
    self._call_other_function()
    self.myvar = 5
    i = 4
    i = i + 5
    if self.myothervar is True:
        self.call_other_function2()
    # ... 其他业务代码

这个装饰器会自动在每一行代码执行时,记录对应的代码文本(或行号信息),完全不需要在业务代码中插入日志语句。

方案2:使用标准库trace模块

Python内置的trace模块专门用于代码执行追踪,可直接利用它生成执行日志,无需手动编写追踪逻辑:

import sys
import trace
import logging

logger = logging.getLogger(__name__)

def run_with_execution_trace(func, *args, **kwargs):
    # 创建追踪器,关闭计数功能,开启行追踪
    tracer = trace.Trace(count=False, trace=True)
    
    # 重定向trace的输出到logger
    original_stdout = sys.stdout
    class LoggerRedirector:
        def write(self, message):
            if message.strip():
                logger.info(f"Trace: {message.strip()}")
    
    sys.stdout = LoggerRedirector()
    try:
        # 运行目标函数并追踪
        tracer.runfunc(func, *args, **kwargs)
    finally:
        # 恢复原stdout
        sys.stdout = original_stdout

# 使用方式:直接调用该函数执行目标函数
run_with_execution_trace(my_annoying_function, self)

trace模块会自动输出每一行执行的代码路径,我们通过重定向标准输出,把这些信息写入日志系统,无需修改原函数。

方案3:分支判断专用日志辅助函数

如果不需要记录每一行,只需要追踪if-else等分支的判断结果,可以写一个轻量的辅助函数,既记录判断逻辑又返回结果:

import logging

logger = logging.getLogger(__name__)

def log_and_return_condition(condition, description):
    condition_result = bool(condition)
    logger.info(f"Condition '{description}' evaluated to {condition_result}")
    return condition_result

# 在目标函数中替换原判断语句
def my_annoying_function(self):
    self._call_other_function()
    self.myvar = 5
    i = 4
    i = i + 5
    if log_and_return_condition(self.myothervar is True, "self.myothervar is True"):
        self.call_other_function2()
    # ... 其他分支判断

这种方式仅针对关键分支添加记录,代码冗余度极低,同时能明确追踪分支走向。

内容的提问来源于stack exchange,提问作者A. L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:40:33