【发布时间】:2017-04-13 05:33:07
【问题描述】:
阅读 Python 的 logging 库的文档(适用于 2.7 版)我遇到了以下问题:
Logger.debug(msg, *args, **kwargs)
[...] 第二个关键字参数是额外的,可用于传递一个字典,该字典用于填充为具有用户定义属性的日志事件创建的 LogRecord 的
__dict__。然后可以随意使用这些自定义属性。例如,它们可以合并到记录的消息中。 [...] 额外传入的字典中的键不应与日志系统使用的键发生冲突。 [emph.我的]
那么为什么会存在这个约束呢?在我看来,这无缘无故地从库中删除了灵活性(由开发人员检查哪些键是内置的,哪些不是)。
假设你想写一个装饰器来记录函数的进入和退出:
def log_entry_exit(func):
def wrapper(*args, **kwargs):
logger.debug('Entry')
result = func(*args, **kwargs)
logger.debug('Exit')
return result
return wrapper
@log_entry_exit
def foo():
pass
假设您还想记录封闭函数的名称:
format_string = '%(funcName)s: %(message)s'
哎呀!这行不通。输出是:
>>> foo()
wrapper: Entry
wrapper: Exit
当然,函数名的计算结果为wrapper,因为那是封闭函数。然而,这不是我想要的。我想要打印装饰函数的函数名。因此,将我的日志调用修改为:
logger.debug('<msg>', extra={'funcName': func.__name__})
但是(正如文档已经指出的那样)这不起作用:
KeyError: "Attempt to overwrite 'funcName' in LogRecord"
尽管如此,对于给定问题,这将是一个非常简单明了的解决方案。
那么,为什么logging 阻止我为内置属性设置自定义值?
【问题讨论】:
-
我不确定这是否真的可以回答。该模块按照文档中的描述工作。至于为什么模块是这样设计的,你得问问开发者。