【问题标题】:Logging repeatable actions in Python在 Python 中记录可重复的操作
【发布时间】:2019-12-19 11:45:39
【问题描述】:

在 Python 3.6 中工作,我想记录可重复的操作,而不需要从函数代码中对记录器进行过多的调用。最好有一个自动选项,以便在函数内的每一行代码评估后吐出日志。这可能吗?

以下是过滤数据之类的最小可重现示例:

# 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]))

问题是我必须为基本相同的操作编写对记录器的可重复调用。

【问题讨论】:

  • 如果您发现对日志记录的调用重复并且“相同的操作”可能其余/主要代码(即不是对日志记录的调用)也是重复的。在示例中,您可以定义一个单独的函数(过滤和日志记录),将 df 作为参数,将上限和下限作为附加参数,并在循环中调用该函数
  • 所以...您想避免一遍又一遍地使用同一行...?你可以做一个包装前一个调用的函数,在返回值之前,它会在参数上做这个特定的日志记录。 (因为每次你有dummy_df= 并且每次日志记录都会跟随。)基本上是def with_log(df): logging...; return df,然后是dummy_df = with_log(dummy_df.loc[dummy_df['col_A'] &gt; 15])。这个版本的with_log 也可以与构造函数一起使用。
  • @buran,我同意在很多情况下确实如此,而且这是一个很棒的呐喊!但是,在我的情况下,条件不能以任何明显的方式重复,所以循环不是一个选项。
  • 替代方案是为每个过滤器定义函数(如果它们如此不同)并在循环体中调用这些函数和单个日志语句。额外的好处 - 这将很容易测试每个功能
  • @h4z3,又一个伟大的呼喊,但出于与上述类似的原因,我需要为每个操作编写一个单独的函数,基本上是一行代码。

标签: python python-3.x logging


【解决方案1】:

假设条件如此不同以至于不可能有一个过滤器功能随着过滤器条件的变化而变化。

# 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)
})

def filter1(df):
    return df.loc[df['col_A'] > 15]

def filter2(df):
    return df.loc[(df['col_B'] > 1500) & (df['col_B'] < 1600)]

filters = (filter1, filter2)

logging.info("There are {} rows remaining".format(dummy_df.shape[0]))
for my_filter in filters:
    dummy_df = my_filter(dummy_df)
    logging.info("There are {} rows remaining".format(dummy_df.shape[0]))

您可以根据需要添加任意数量的过滤器

【讨论】:

  • 我编辑了我的答案,因为 filter2 使用(错误地)全局变量 dummy_df 而不是 df 参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 2016-03-15
相关资源
最近更新 更多