如何解决手动将 StreamHandler 添加到记录器会破坏 IPython 提示
如果我从 IPython interperter 内的另一个线程登录(使用标准 python 日志记录模块),则提示会针对每个输出的日志移动,如下所示:
In [4]: threading.Thread(target=function_that_logs).start()
ERROR:root:Error message 1
In [5]: i_am_trying_
In [4]: threading.Thread(target=function_that_logs).start()
ERROR:root:Error message 1
ERROR:root:Error message 2
In [5]: i_am_trying_to_type_here
但是,如果我手动添加一个StreamHandler,日志输出不再移动提示。连续记录时,这几乎无法使用提示。
In [4]: threading.Thread(target=function_that_logs).start()
In [5]: ERROR:root:Error message 1
i_am_trying_ERROR:root:Error message 2
to_type_here
不同之处似乎是使用了围绕 stdout 的不同包装器,具体取决于创建处理程序的时间/地点。 我尝试查看 IPython 文档,但并没有真正找到任何有用的东西。 如果有人能解释这里发生的事情,或者为我指明正确的方向,我将不胜感激。
请参阅下面的完整工作示例:
> ipython
Python 3.6.8 (tags/v3.6.8:3c6b436a57,Dec 24 2018,00:16:47) [MSC v.1916 64 bit (AMD64)]
Type 'copyright','credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import threading,time,logging
In [2]: def foo():
...: for i in range(15):
...: time.sleep(1)
...: logging.error(f"bar {i}")
...:
In [3]: logging.root.handlers
Out[3]: []
In [4]: logging.basicConfig()
In [5]: logging.root.handlers
Out[5]: [<StreamHandler <stderr> (NOTSET)>]
In [3]: logging.root.handlers[0].stream
Out[3]: <colorama.ansitowin32.StreamWrapper at 0x11dc44b9668>
In [7]: threading.Thread(target=foo).start()
In [8]: ERROR:root:bar 0
ERROR:root:bar 1
ERROR:root:bar 2
ERROR:root:bar 3
ERROR:root:bar 4
ERROR:root:bar 5
ERROR:root:bar 6
ERROR:root:bar 7
ERROR:root:bar 8
ERROR:root:bar 9
ERROR:root:bar 10
ERROR:root:bar 11
ERROR:root:bar 12
ERROR:root:bar 13
ERROR:root:bar 14
> ipython
Python 3.6.8 (tags/v3.6.8:3c6b436a57,logging
In [2]: def foo():
...: for i in range(15):
...: time.sleep(1)
...: logging.error(f"bar {i}")
...:
In [3]: logging.root.handlers
Out[3]: []
In [4]: threading.Thread(target=foo).start()
ERROR:root:bar 0
ERROR:root:bar 1
ERROR:root:bar 2
ERROR:root:bar 3
ERROR:root:bar 4
ERROR:root:bar 5
ERROR:root:bar 6
ERROR:root:bar 7
ERROR:root:bar 8
ERROR:root:bar 9
ERROR:root:bar 10
ERROR:root:bar 11
ERROR:root:bar 12
ERROR:root:bar 13
ERROR:root:bar 14
In [5]: logging.root.handlers
Out[5]: [<StreamHandler (NOTSET)>]
In [6]: logging.root.handlers[0].stream
Out[6]: <prompt_toolkit.patch_stdout.StdoutProxy at 0x1321dc82ac8>
编辑:我也尝试手动添加 StdoutProxy,但是我根本没有得到任何输出:
> ipython
Python 3.6.8 (tags/v3.6.8:3c6b436a57,logging,prompt_toolkit
In [2]: def foo():
...: for i in range(15):
...: time.sleep(1)
...: logging.error(f"bar {i}")
...:
In [3]: logging.root.addHandler(logging.StreamHandler(prompt_toolkit.patch_stdout.StdoutProxy()))
In [4]: threading.Thread(target=foo).start()
In [5]:
EDIT2:我做了更多的实验。似乎存在竞争条件导致不同的流包装器用于标准输出:
In [32]: logging.root.handlers = []
In [33]: threading.Thread(target=lambda: time.sleep(1) or logging.basicConfig()).start()
In [34]: logging.root.handlers[0].stream
Out[34]: <prompt_toolkit.patch_stdout.StdoutProxy at 0x20a2f4d1860>
In [35]: logging.root.handlers = []
In [36]: threading.Thread(target=lambda: logging.basicConfig()).start()
In [37]: logging.root.handlers[0].stream
Out[37]: <colorama.ansitowin32.StreamWrapper at 0x20a2e2f9630>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。