尽早设置日志记录:捕获导入过程中发出的警告



我希望所有警告都能像处理日志一样处理。甚至这些都是在导入库时发出的。

这意味着必须在导入库之前完成日志记录的配置。

经过一段时间的搜索,我认为在自定义sitecustomize.py中配置日志记录可能是一个解决方案。

sitecustomize.py是一种黑魔法,只有很少的人知道它,甚至很少有人使用它

有没有更明显的方法可以确保在导入库之前完成日志配置?

不幸的是,似乎没有办法通过环境变量配置日志记录。

更新

根据我的观点,我没有得到可以接受的答案。我认为您需要将日志记录分为两个责任领域:

  • 环境:设置日志记录:哪种格式,哪些文件
  • 代码:使用日志记录。发出信息、警告和错误消息

一旦python解释器执行了第一行代码,"环境"区域就将责任交给了代码。现在进行任何配置都为时已晚。我希望将日志记录设置为调用python解释器的一部分。

一种解决方案可能是环境变量:

PYTHON_LOGGING_CONFIG=/path-to-env/etc/config.yaml

或者给解释器一个论点:

python --logging-config=path-to-env/etc/config.yaml script.py

如果您想让日志记录覆盖导入内容,显然无法在导入其他内容之前显式配置日志记录。

然而,如果您希望日志记录配置更加明显,那么有各种技巧可以帮助您做到这一点。例如,您的main脚本可以像这样短,只是为了突出特殊情况:

import siteconfiguration
siteconfiguration.configure_site()  # This must be done before any other import
import application

if __name__ == "__main__":
    application.run()

这仍然打破了将所有进口商品置于首位的规则,但也清楚地说明了为什么要这样做。每个使用该代码的人都会理解您的意图。

特殊情况不足以打破规则。

尽管实用胜过纯粹。

(The Zen of Python,Tim Peters著)

显式导入机器

如果导入的顺序很重要,或者文件顶部的导入语句之间有代码,我不喜欢。我喜欢用自动化工具清理我的代码,这可能会破坏东西。

如果您希望先发生某些事情,请先执行。如果要修改import的工作方式,则需要在调用import之前进行修改。如果问题是由编辑器引起的,那么可以更改它,找到如何不对子句重新排序,或者将代码放在名称第一的模块中,例如import aaaaaa_logging_overrides

假设您的代码看起来像@zvone的解决方案;并且您的编辑器从重新排序导入

import siteconfiguration
siteconfiguration.configure_site()  # This must be done before any other import
import application

import application
import siteconfiguration
siteconfiguration.configure_site()  # This must be done before any other import

我可能会更换编辑。这与将下面的代码搞砸非常相似,很明显,编辑器不应该重新排序导入并将其放在路径操作之前:

import sys
sys.path.append('/nfs/some/corp/dir')
import corp.module

使用站点自定义

您的python内容位于sys.prefix下。应该有:

  • lib/python-*/site.py
  • lib/python-*/site-packages
  • lib/python-*/sitecustomize.py(可选,取决于管理员是否使用)

例如

(test)/tmp/test > (4) cat lib/python2.7/sitecustomize.py
print 'imported sitecustomize'
(test)/tmp/test > (4) cat foo.py 
print 'executing foo'

运行示例:

(test)/tmp/test > (4) python foo.py 
imported sitecustomize
executing foo

正如你所说,这是黑魔法;因为运行脚本的用户可能不会期望其他一些随机代码(读:可能不在他们的控制之下,也不是标准发行版的一部分)运行和更改行为。

最新更新