我有两个python脚本(test1.py,test2.py),用于初始化自己的记录器。 test2.py从test1.py导入一个变量。奇怪的是,来自test1.py的记录器也会自动导入test2.py。
test1.py
import logging
import logging.handlers
LOG_FILENAME = '1.log'
rootLogger = logging.getLogger("default")
rootLogger.setLevel(logging.DEBUG)
# Set up a specific logger with our desired output level
consoleHandler = logging.StreamHandler()
rootLogger.addHandler(consoleHandler)
# Add the log message handler to the logger
handler = logging.FileHandler( LOG_FILENAME)
rootLogger.addHandler(handler)
a = 1
b = 2
test2.py
import logging
import logging.handlers
LOG_FILENAME = '2.log'
rootLogger = logging.getLogger("default")
rootLogger.setLevel(logging.DEBUG)
# Set up a specific logger with our desired output level
consoleHandler = logging.StreamHandler()
rootLogger.addHandler(consoleHandler)
# Add the log message handler to the logger
handler = logging.FileHandler( LOG_FILENAME)
rootLogger.addHandler(handler)
a = 3
from test1 import b
rootLogger.debug("a:%s",a)
rootLogger.debug("b:%s",b)
现在当我运行test2.py时,我希望只能调用test2.py中的rootLogger。更重要的是,我预计只会写入2.log
。但奇怪的是,除了控制台上的重复输出外,还会生成1.log
。
$ python test2.py
a:3
a:3
b:2
b:2
$ cat 1.log
a:3
b:2
为什么会发生这种情况,以及避免此类情况的最佳做法是什么。
更新
我更改了getLogger调用以区分不同的记录器。
rootLogger = logging.getLogger(__name__)
但即使这样,“1.log”文件也会被创建,但这次它仍然是空的。
我理解我理想情况下不应该将rootLogger声明为全局,但是我必须将rootLogger处理程序传递给所有函数调用。
答案 0 :(得分:0)
稍后的一些评论(感谢@schwobaseggl),我意识到了明显的问题。我遇到的问题是两个概念的组合:
从模块导入任何内容时,即使它是单个变量,也会执行所有模块级代码。
对具有相同名称的getLogger()的多次调用将始终返回对同一Logger对象的引用。 https://docs.python.org/2/library/logging.html
所以基本上,因为我在两个脚本中都使用了相同的记录器名称,并且两者中的global module code
按顺序运行,我偶然在同一个记录器上添加了两次不同的FileHandler。
<强>解决方案强>
始终将记录器初始化代码放在if __name__ == '__main__':
块中。
import logging
import logging.handlers
a = 1
b = 2
if __name__ == '__main__':
LOG_FILENAME = '1.log'
rootLogger = logging.getLogger(__name__)
rootLogger.setLevel(logging.DEBUG)
# Set up a specific logger with our desired output level
consoleHandler = logging.StreamHandler()
rootLogger.addHandler(consoleHandler)
# Add the log message handler to the logger
handler = logging.FileHandler( LOG_FILENAME)
rootLogger.addHandler(handler)