如何将多参数print输出重定向至Python logging日志功能?
解决print()重定向到logging的多参数问题
这个问题我之前也碰到过!直接把print赋值给logging.debug之所以只支持单个参数,核心原因是两者的参数处理逻辑完全不同:
logging.debug的第一个参数是格式化消息字符串,后续参数是用来填充字符串占位符的(比如logging.debug("Hello %s", "world"));- 而原生
print是接受任意多个位置参数,默认用空格分隔所有参数,最后追加换行符。
当你传多个参数给赋值后的print时,logging.debug会把它们当成格式化参数而非需要拼接的内容,自然就会出现错误或不符合预期的输出。
解决方案:写一个模拟print行为的包装函数
我们可以自定义一个函数,完全复刻print的参数处理逻辑,再把处理后的字符串传给logging.debug。这样不管传多少个参数,都能和原生print一样正常工作。
完整代码示例:
import logging # 配置logging(保持你原来的配置即可) logging.basicConfig( filename="logname", filemode='a', format='%(asctime)s,%(msecs)03d %(name)s %(levelname)s %(message)s', datefmt='%D %H:%M:%S', level=logging.DEBUG ) def custom_print(*args, sep=' ', end='\n', **kwargs): # 1. 把所有参数转为字符串,用sep分隔 # 2. 追加end指定的结尾字符 message = sep.join(str(arg) for arg in args) + end # 把处理好的消息传给logging.debug,保留logging的可选参数(比如exc_info) logging.debug(message, **kwargs) # 替换原生print函数 print = custom_print # 测试用例 print("hallo") # 单参数正常输出 print("makes", "no", "error") # 多参数正常拼接 print("custom", "sep", sep='-') # 自定义分隔符 print("no newline", end='') # 自定义结尾
效果验证
运行上述代码后,日志文件里会生成如下内容(时间戳会根据实际运行时间变化):
03/30/18 14:06:11,881 root DEBUG hallo 03/30/18 14:06:11,882 root DEBUG makes no error 03/30/18 14:06:11,882 root DEBUG custom-sep 03/30/18 14:06:11,882 root DEBUG no newline
如果需要支持Python 3.3+的flush参数,可以在函数里添加flush=False参数,然后根据需要调用日志handler的flush方法,不过默认日志配置下一般不需要额外处理。
内容的提问来源于stack exchange,提问作者user8042669




