我有以下代码设置记录器:
import logging
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO)
log = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
log.addHandler(handler)
log.info('abc')
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到如下输出:
2020-06-10 13:32:16,245 INFO: abc
abc
Run Code Online (Sandbox Code Playgroud)
我认为第一个是控制台输出?我如何摆脱重复的?
更新
谢谢大家的答案,现在我知道为什么我会得到重复,我这样做的原因是因为默认流处理程序不会输出到标准输出,所以我用谷歌搜索并看到有人添加了标准输出处理程序,因此我得到了 2 个流处理程序(控制台和标准输出)。
我现在再次阅读了关于 的文档basicConfig(),我已经找到了实现我想要的最简单的方法:
2020-06-10 13:32:16,245 INFO: abc
abc
Run Code Online (Sandbox Code Playgroud)
此调用logging.basicConfig将已经添加一个流处理程序(到 stderr),因此没有理由手动添加另一个流处理程序。这样做会导致重复输出到终端,在您的情况下,每个日志事件都会在stderr 和 stdout上打印。
如果您希望流处理程序为 stdout 而不是 stderr,只需basicConfig通过指定stream或handlers关键字(文档)相应地调整调用。
您还可以清理其他两件事:使用绑定到模块上下文的记录器而不是直接使用根记录器,并避免在导入时__name__配置模块。logging如果您在导入时过于急切地配置日志系统,那么用户(和测试套件)将无法再以不同的方式对其进行配置。
import logging
# create your logger as module level global
log = logging.getLogger(__name__)
def main():
# configure logging at entry point (so it is not configured at *import* time)
fmt = '%(asctime)s %(levelname)s: %(message)s'
logging.basicConfig(format=fmt, level=logging.INFO) # streamhandler to stderr
log.info('abc')
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)