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

Python 3.6中如何自动记录重复操作日志?避免频繁调用Logger

问题:如何在Python 3.6中自动记录操作日志(避免重复调用Logger)

在Python 3.6环境下,我希望记录重复操作,同时避免在函数代码中频繁调用Logger。理想情况下,能实现函数内每行代码执行后自动输出日志,请问是否可行?以下是数据过滤场景的最小可复现示例:

# Import libraries
import pandas as pd
import numpy as np
import logging

# Set up the logger and a dummy data frame
logger = logging.getLogger()
logger.setLevel(logging.INFO)
dummy_df = pd.DataFrame({
 'col_A': np.arange(1, 1000, 1),
 'col_B': np.arange(1001, 2000, 1)
})

# Subset rows of the dataframe
logging.info("There are {} rows remaining".format(dummy_df.shape[0]))
# Removing values A below 15
dummy_df = dummy_df.loc[dummy_df['col_A'] > 15]
logging.info("There are {} rows remaining".format(dummy_df.shape[0]))
# Removing values B below 1500 and above 1600
dummy_df = dummy_df.loc[(dummy_df['col_B'] > 1500) & (dummy_df['col_B'] < 1600)]
logging.info("There are {} rows remaining".format(dummy_df.shape[0]))

当前问题在于,对于本质相同的操作,我不得不重复编写Logger调用语句。


解决方案

当然可行!不过先得区分你的核心需求:是避免重复写日志语句,还是真的需要每行代码执行后都自动打日志?咱们分两种情况来解决:

一、优先解决重复日志的痛点(最实用)

你现在的重复操作都是记录DataFrame的行数,完全可以把这个日志逻辑封装成一个辅助函数,这样就不用每次都写logging.info那套格式了:

def log_df_row_count(df, step_desc):
    """记录DataFrame当前行数,附带操作步骤描述"""
    row_count = df.shape[0]
    logger.info(f"[{step_desc}] 剩余行数:{row_count}")

然后改造你的代码,用这个函数替代重复的日志调用:

# 初始化后记录初始行数
log_df_row_count(dummy_df, "初始数据")

# 过滤col_A < 15的行
dummy_df = dummy_df.loc[dummy_df['col_A'] > 15]
log_df_row_count(dummy_df, "移除col_A小于15的行")

# 过滤col_B不在1500-1600之间的行
dummy_df = dummy_df.loc[(dummy_df['col_B'] > 1500) & (dummy_df['col_B'] < 1600)]
log_df_row_count(dummy_df, "移除col_B超出1500-1600范围的行")

这样代码简洁多了,而且日志还加了步骤描述,可读性更强!

二、实现每行代码执行后自动日志(适合特殊场景)

如果确实需要追踪每行代码的执行情况,咱们可以用装饰器+代码执行追踪的方式实现,但要注意这种方式比较“hack”,适合简单脚本场景,复杂函数可能会有兼容性问题:

1. 实现自动日志装饰器

import sys
import inspect

def log_each_executed_line(func):
    def wrapper(*args, **kwargs):
        # 获取目标函数的源代码
        func_source = inspect.getsource(func)
        # 拆分代码行,过滤空行和注释
        code_lines = [
            line.strip() 
            for line in func_source.split('\n') 
            if line.strip() and not line.strip().startswith('#')
        ]
        
        # 构建函数的执行命名空间
        exec_namespace = func.__globals__.copy()
        # 把函数参数也加入命名空间(简单处理)
        exec_namespace.update(locals())
        
        for line in code_lines:
            try:
                # 执行当前代码行
                exec(line, exec_namespace, exec_namespace)
                # 记录执行日志
                logger.info(f"已执行代码行:{line}")
                
                # 如果是赋值语句,额外记录变量结果(针对DataFrame做特殊处理)
                if '=' in line:
                    var_name = line.split('=')[0].strip()
                    if var_name in exec_namespace:
                        var_value = exec_namespace[var_name]
                        if hasattr(var_value, 'shape'):
                            logger.info(f"  变量{var_name}状态:行数={var_value.shape[0]},列数={var_value.shape[1]}")
                        else:
                            logger.info(f"  变量{var_name}值:{var_value}")
            except Exception as e:
                logger.error(f"执行代码行出错:{line} - 错误信息:{str(e)}")
                raise e
        
        # 返回函数的执行结果(如果有的话)
        return exec_namespace.get('result', None)
    return wrapper

2. 用装饰器标记需要自动日志的函数

把你的数据处理逻辑放到一个函数里,然后加上装饰器:

@log_each_executed_line
def process_dummy_data():
    import pandas as pd
    import numpy as np
    
    # 初始化数据
    dummy_df = pd.DataFrame({
        'col_A': np.arange(1, 1000, 1),
        'col_B': np.arange(1001, 2000, 1)
    })
    
    # 过滤col_A <15的行
    dummy_df = dummy_df.loc[dummy_df['col_A'] > 15]
    
    # 过滤col_B范围外的行
    dummy_df = dummy_df.loc[(dummy_df['col_B'] > 1500) & (dummy_df['col_B'] < 1600)]
    
    # 把最终结果存到result变量,方便装饰器返回
    result = dummy_df

3. 调用函数触发自动日志

process_dummy_data()

运行后,每一行代码执行都会自动输出日志,还会记录变量的状态(比如DataFrame的行数)。不过要注意,这种方式对复杂函数(比如嵌套循环、条件分支、内部函数调用)的处理会有局限,而且exec的性能和安全性需要留意。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:17:45