如何在 ipython 会话中完全重置 Python stdlib 日志记录模块?
我想在 ipython 会话中使用 %run 重复调用 Python 脚本,并根据通过 %run 传递的 cmdline 参数来记录每个脚本。
例如,在调试 cmd.py 时,我可能会随着时间的推移想要运行:
%run cmd.py
... logs with default behavior, e.g. to STDERR with root level WARN
%run cmd.py --log_level DEBUG --log_file /tmp/cmd.out
... logs with root level DEBUG to a file
%run cmd.py --log_level ERROR
不幸的是,这很困难,因为由logging.basicConfig创建的日志记录状态在第一个%run命令之后仍然存在(对于所有模块来说更普遍如此,并且在使用时通常是可取的) %跑步)。
我意识到,一般来说,像上面这样的一系列 %run 命令与在新进程中运行每个命令不同。不过,如果像log_level和log_file这样的东西可以重新初始化的话,那就非常方便了。
我在 cmd.py 中尝试过类似的操作:
import logging_config # parse logging config from sys.argv
reload(logging_config) # re-parse cmdline if using %run multiple times
而logging_config.py 确实(压缩):
if logging_initialized:
logging.getLogger().setLevel(lvl)
else:
logging.basicConfig(level=lvl)
logging_initialized = True
它适用于简单的情况,但如果 cmd.py 导入也使用日志记录的库则无效。我还尝试了logging.shutdown()(在每个cmd.py结束时调用),但这似乎没有帮助。
I'd like to make repeated calls to Python scripts using %run in an ipython session, and for each of those scripts to log based on cmdline arguments passed via %run.
For example while debugging cmd.py I might over time want to run:
%run cmd.py
... logs with default behavior, e.g. to STDERR with root level WARN
%run cmd.py --log_level DEBUG --log_file /tmp/cmd.out
... logs with root level DEBUG to a file
%run cmd.py --log_level ERROR
Unfortunately this is difficult because the logging state created by logging.basicConfig persists after the first %run command (as is more generally true of all modules, and often desirable when using %run).
I realize that in full generality a series of %run commands like above will not be the same as running each command in a new process. However, it would be very convenient if things like the log_level and log_file could be re-initialized.
I've tried something like this in cmd.py:
import logging_config # parse logging config from sys.argv
reload(logging_config) # re-parse cmdline if using %run multiple times
and logging_config.py does (condensed):
if logging_initialized:
logging.getLogger().setLevel(lvl)
else:
logging.basicConfig(level=lvl)
logging_initialized = True
It works for simple cases but not if cmd.py imports libraries that also use logging. I've also experimented with logging.shutdown() (called at conclusion of each cmd.py) but that does not seem to help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要将 basicConfig() 用于这种使用方式 - 它用于简单的一次性配置,并且正如文档所述,第一次调用之后的后续调用没有效果(它仅在以下情况下执行任何操作):根记录器没有处理程序)。当您的脚本从 shell 提示符运行时,这没问题,但不是从交互式解释器、IPython、IDLE、PythonWin 或与您交互的进程不会退出的其他类似环境运行。
相反,请使用编程配置,或 fileConfig() 或 dictConfig() - 这些模式可以用新的配置完全替换现有的日志配置。
Don't use basicConfig() for this style of usage - it's meant for simple one-off configuration and, as the documentation says, subsequent calls after the first have no effect (it only does anything if the root logger has no handlers). This will be fine when your script is run from the shell prompt, but not from the interactive interpreter, IPython, IDLE, PythonWin, or other similar environment where the process you're interacting with doesn't exit.
Instead, use programmatic configuration, or fileConfig() or dictConfig() - these have modes where the completely replace the existing logging configuration with a new one.