阅读Python的logging库文档(版本为2.7),我发现以下内容:
Logger.debug(msg, *args, **kwargs)
[...] 第二个关键字参数是extra,可以用于传递一个字典,该字典用于填充创建日志事件的LogRecord的
__dict__属性中的用户定义属性。然后可以根据需要使用这些自定义属性。例如,它们可以并入已记录的消息中。[...] 在extra传递的字典中的键不应与日志系统使用的键冲突。 [强调我的]
那么为什么存在这种限制?在我看来,这会使库变得不够灵活,而且没有好的理由(开发人员应该检查哪些键是内置的,哪些不是)。
想象一下,您想编写一个装饰器,用于记录函数的进入和退出:
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会阻止我设置内置属性的自定义值?