【问题标题】:How does logging across multiple modules work?跨多个模块的日志记录如何工作?
【发布时间】:2019-01-16 01:24:48
【问题描述】:

根据logging模块的cookbook

在多个模块中使用日志记录

logging.getLogger('someLogger') 的多次调用会返回对同一记录器对象的引用。这不仅在同一个模块内是正确的,而且跨模块也是如此,只要它在同一个 Python 解释器进程中。对同一个对象的引用是正确的;此外,应用程序代码可以在一个模块中定义和配置父记录器,并在单独的模块中创建(但不配置)子记录器,所有对子记录器的调用都将传递给父记录器。

这是如何工作的? (我尝试查看模块源代码,但无法弄清楚。)到目前为止,我不知道我可以定义可跨模块访问的“超级全局”对象。 为了帮助我理解 logging 是如何做到的,你能告诉我如何让以下工作:

foo.py,做

import my_module

my_module.set_my_value(42)

在“bar.py”中,做

import my_module

print(my_module.get_my_value())  # Should print 42

【问题讨论】:

    标签: python python-3.x logging module


    【解决方案1】:

    首先,做你想做的事是微不足道的。当您 import 一个模块时,该模块对象的单个实例仅由 imports 的任何其他人共享,1 并且该模块对象的属性只是模块的全局变量。所以:

    # script.py
    import cheese
    import eggs
    cheese.beans = 10
    eggs.dostuff()
    
    # eggs.py
    import cheese
    print(cheese.beans)
    print(cheese.ham)
    
    # cheese.py
    ham = 20
    

    如果您运行script.py,它将打印 10,然后是 20。

    您当然必须小心顶级模块代码,它按照模块首次导入的顺序运行(这可能很难解决),2 和代码在脚本中(任何人都不应该将其作为模块导入)3,但除此之外,它就可以正常工作,不需要任何特殊的 getter 和 setter 函数。

    (如果你出于某种原因需要 getter 和 setter 函数,同样适用于任何对象的 getattrsetattr 在模块对象上也能正常工作。)

    现在,logging 如何发挥它的魔力?简单的;它只是在其全局变量中存储一个字典。由于模块只有一个实例,因此它的全局变量也只有一个实例,因此 dict 也只有一个实例。


    1。如果你想知道 that 是如何在幕后工作的……当你执行import cheese 时,Python 所做的(默认情况下,假设你没有安装任何奇怪的导入钩子)是:首先,是否存在sys.modules['cheese']?如果没有,找到cheese的规范,用它找到一个加载器,用加载器加载代码,exec代码,并将结果存储为sys.modules['cheese']。然后只需return sys.modules['cheese']。这就是为什么每个模块只运行一次顶级代码,不管你import它多少次,这也是为什么imports它的每个人都共享同一个模块对象的副本。

    2。你的例子只适用于my_module.my_value = 42print(my_module.myvalue)——如果foobar 之前得到imported。但是如果bar首先得到imported,它将得到一个AttributeError,因为显然还没有人设置my_module.my_value

    3。主要原因是当你运行script.py时,它不是作为一个名为script的模块运行的,而是作为一个名为__main__的模块运行的。这就是if __name__ == '__main__': 守卫成语起作用的原因。但是如果其他人做了一个import scriptscript 不在sys.modules 中,所以 Python 将加载并执行一个单独的 script.py 副本,它有自己单独的全局变量。

    【讨论】:

    • 现在我有点尴尬,因为我不知道(或者没有正确考虑)。感谢您详细解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多