在python日志教程中,有一个带有两个python脚本的例子:myapp.py和mylib.py
代码是:
# myapp.py
import logging
import mylib
def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')
if __name__ == '__main__':
    main()
和
# mylib.py
import logging
def do_something():
    logging.info('Doing something')
我没有得到的是如何使用basicConfigin myapp.py更改日志记录行为mylib.py.
我认为在Python中,当您在两个不同的脚本中导入相同的模块时,它们完全断开连接,因为第一个myapp.logging和第二个完成mylib.logging.
编辑:
我将mylib.py代码更改为
# mylib.py
import logging
def do_something():
    logging.warning('Doing something')
do_something()
当我运行myapp.py时,日志现在在控制台中打印,不再出现在日志文件中.怎么可能?
在理解python的模块时有一个错误(如果我可以称之为):
我认为在Python中,当您在两个不同的脚本中导入相同的模块时,它们完全断开连接,因为第一个
myapp.logging和第二个完成mylib.logging.
不是这种情况.
import遇到该语句时会解释该语句,当您在主程序(python myapp.py或等效程序)上运行python时,会执行以下行:
import logging
(导入logging模块),
import mylib
(导入你的图书馆mylib.py),
def main():
(将名称绑定main到函数的已编译字节码),并且:
if __name__ == '__main__':
    main()
(运行你的,main因为本地名称__name__实际上绑定到一个比较等于字符串的字符串__main__).
到目前为止,这可能不是很令人惊讶(除了可能def main()是在导入时遇到的点myapp.py).
可能令人惊讶的部分是在执行两个import语句期间发生的事情.
导入机制已经发展了一点(并且在Python3中与Python2有些不同)但实质上它做了以下各种事情:
sys.path)sys.modules(见下文)<type 'module'>或其中的名称)绑定到您提供的名称(隐式使用常规import,显式使用from ... import ... as name).其中一个关键项目是上面的斜体部分.该模块实际上是在第一个模块上运行import.导入成功的结果是模块实例,它被添加到sys.modules字典中:
$ python2
...
>>> import sys
>>> x = sys.modules['copy_reg']
>>> print x
<module 'copy_reg' from '/usr/local/lib/python2.7/copy_reg.pyc'>
如果,在这一点上,你要求python 重新导入模块,它将悄悄地几乎什么都不做:
>>> import copy_reg
>>> 
这里发生的是Python注意到模块已经加载,sys.modules因此它只是提取已经加载的模块实体(我们也绑定到x上面的符号).然后它将名称绑定copy_reg到此已存在的模块.如果你import copy_reg as y:
>>> import copy_reg as y
该名称另外绑定到符号y:
>>> print x, y, copy_reg
<module 'copy_reg' from '/usr/local/lib/python2.7/copy_reg.pyc'> <module 'copy_reg' from '/usr/local/lib/python2.7/copy_reg.pyc'> <module 'copy_reg' from '/usr/local/lib/python2.7/copy_reg.pyc'>
要看到这些实际上是同一个模块,我们可以使用该id函数,它打印底层对象的内部地址:
>>> print id(x), id(y), id(copy_reg)
34367067648 34367067648 34367067648
(不同的Python运行,或者不同的版本,可能会在这里产生不同的3组地址值,但这三个都匹配,因为这些都是指同一个模块).
在任何情况下,在你main的myapp,符号logging是指相同的logging模块为标志logging的mylib.
在你的原代码,调用(来自do_something于mylib)logging.warning打印的消息后,您main在myapp已调用日志记录配置代码.因此,日志消息按照指示进行.
在编辑中,一旦语句加载以创建模块,您就已经mylib无条件地调用(通过do_something)logging.warning函数.这种情况发生在早期,在绑定到代码之前和调用之前.所以这个消息在控制台上出现了.import mylibmyilbmyappmainmain
由日志代码决定是否服从(稍后)basicConfig调用你的main.正如您在自己的示例中所看到的,它不会在打印消息后尝试重定向根配置(这是因为我记得当时它已经设置了内部日志处理程序).
| 归档时间: | 
 | 
| 查看次数: | 2823 次 | 
| 最近记录: |