【问题标题】:How to implement an implicit logger in Python?如何在 Python 中实现隐式记录器?
【发布时间】:2022-01-06 22:26:50
【问题描述】:

我想向 Python 代码库添加一些有用的日志记录。

我希望添加大致形式的日志记录:

[2022-01-06 10:00:01] function foo called with args x=1, y=22, z=3
[2022-01-06 10:00:05] function foo returned 1416
[2022-01-06 10:00:13] function bar called with args w=1416
[2022-01-06 10:00:16] function bar returned None

我可以通过使用装饰器包装代码库中的所有函数来做到这一点,但是有更好的方法吗?至少要指明函数调用的时间戳和顺序。

我可以实现装饰器:

def logthis(func):
    def inner(*args, **kwargs):
        logger.info(f'Calling {func.__name__} with args={args} and kwargs={kwargs}')
        ans = func(*args, **kwargs)
        logger.info(f'Function {func.__name__} returned {ans}')
        return ans
    return inner

@logthis
def foo(x, y, z):
   return x+y+z

@logthis
def bar(w):
   return None

这很好用;前提是我很乐意将它添加到我的整个代码库中。

【问题讨论】:

  • 不,装饰师是你最好的选择。
  • 你需要显式地记录参数和返回值,这样做自然是有顺序的,但可以很容易地添加时间戳 - docs.python.org/3/howto/…
  • 我真的很想避免为了记录函数调用而添加数百行代码。我现在继续找。
  • 尼特:你的装饰器应该返回ans,而不是第二次调用该函数。
  • 记录你的代码库中的每一个函数将是巨大的开销,而且没有你想象的那么有用。

标签: python logging


【解决方案1】:

您可以使用inspect 模块。我通常使用它来实现我出于各种原因使用的“获取调用此函数的函数的文件路径”方法。 inspect.stack() (see this) 可能是您正在寻找的,因为您可以在呼叫者列表中查找并创建有关它的信息。

从那里我认为你唯一的问题是如何记录时间。另一个想法是两个为整个类创建一个包装器,或者为您传递__locals__() 的函数创建一个函数,以获取所有函数并将装饰器应用于它们。该方法在某种程度上涉及元编程,因为您必须重建类对象 /update/wrap 他们的所有功能,就像您拥有的那样,但它可以为您节省大量繁琐的工作。

另见traceback module

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多