Python 为什么logger.info()只在调用logging.info()后出现?
我正在使用Python 3.6.4。我第一次遇到的问题是,Python 为什么logger.info()只在调用logging.info()后出现?,python,python-3.x,logging,Python,Python 3.x,Logging,我正在使用Python 3.6.4。我第一次遇到的问题是,logger.setLevel(logging.INFO)被忽略,这让我感到困惑,并引发了这个问题 根据下面的代码 1。为什么logging.info('2')在代码段2中打印,而不是在1中打印?(难道logging.info()不是模块级函数吗?为什么命名记录器会影响此调用?) 2。为什么打印的是logger.info('3'),而不是logger.info('1')? 片段1 片段2 正如您所指出的,代码片段之间的区别在于如何获取lo
logger.setLevel(logging.INFO)
被忽略,这让我感到困惑,并引发了这个问题
根据下面的代码
1。为什么logging.info('2')
在代码段2中打印,而不是在1中打印?(难道logging.info()
不是模块级函数吗?为什么命名记录器会影响此调用?)
2。为什么打印的是logger.info('3')
,而不是logger.info('1')
?
片段1
片段2
正如您所指出的,代码片段之间的区别在于如何获取
logger
对象:
logger = logging.getLogger('foo')
logger = logging.getLogger()
关键是,在第二种情况下,您将获得“根”记录器。另一方面,在第一种情况下,您将得到一个名为foo
的根的“子日志”
现在,让我们一步一步走
logger.setLevel(logging.INFO)
在这里您可以设置记录器的级别。在第一种情况下,您正在设置记录器foo
的级别。在创建时,新的记录者没有级别,所以他们处理每一条消息;这里您的意思是,只应处理严重性INFO
或更高的消息。但是,在第二种情况下,logger
是根记录器。这里令人困惑的是,与新的记录器不同,根记录器的默认级别是WARN
,因此,除非您更改它,否则不会处理低于该级别的任何内容。因此,在这一行之后:
- 在第一个代码段中,根记录器设置为
级别,而WARN
记录器设置为foo
级别INFO
- 在第二个代码段中,根记录器设置为
级别INFO
INFO
,并且logger
设置为该严重性,因此将处理该消息。但是,logger
中没有设置任何处理程序,因此实际上没有对消息进行任何处理
logging.info('2')
现在这更有趣了。这里重要的是logging.info
实际上做了什么,这与调用根记录器对象的info
方法不同:
在根记录器上记录严重性为“INFO”的消息。如果记录器有
没有处理程序,请调用basicConfig()以添加具有预定义
格式
因此,如果没有为根记录器注册处理程序,则此函数将自行生成控制台处理程序。因此,根记录器或子记录器接收到的任何消息现在都将打印到控制台。然而,在第一种情况下,根记录器仍然有其默认的严重性过滤器,WARN
,因此控制台处理程序被注册,但消息实际上被忽略。但是,在第二种情况下,您将根记录器的严重性级别设置为INFO
,因此消息由控制台处理程序处理和打印
logger.info('3')
希望这现在能有意义。现在您有了一个连接到根记录器的控制台处理程序。在第一种情况下,logger
是foo
记录器,其严重性被设置为INFO
,因此消息被处理,并且由于它是根记录器的子记录器,因此它由为该记录器注册的控制台处理程序打印。在第二种情况下,您只是登录到根记录器,它具有INFO
严重性和注册的控制台处理程序
logger.info('3')
请注意,在第一种情况的最后一行中,foo
记录器处理的消息由根记录器中注册的处理程序处理,即使根记录器的严重性级别为WARN
。日志处理程序不负责按严重性进行过滤,这是由日志记录程序本身完成的,因此,一旦日志记录程序决定应处理消息,它将由其所有处理程序和来自父日志记录程序的处理程序处理。这是一个非常有用的功能,因为它允许您拥有更高的系统级日志级别,而对于您更感兴趣的特定模块(例如调试或简单报告)可以使用较低的日志级别。请参阅该帖子上的:
如果您没有使用任何处理程序配置日志记录(如在文章中-您只为日志记录程序配置了一个级别,但在任何地方都没有处理程序),您将获得一个内部处理程序“最后手段”,该处理程序设置为仅输出警告级别的消息(没有其他格式)
您的级别当前低于警告
,因此不会输出。这会随着对basicConfig()
的调用而改变,您可以/应该显式地执行该操作,否则直到从logging.info
(或其他方便函数之一)调用它时才会处理它
文件规定:
注意委托给根记录器的上述模块级便利函数调用basicConfig()
,以确保至少有一个处理程序可用。因此,在2.7.1和3.2之前的Python版本中,不应在线程中使用它们,除非在线程启动之前至少向根记录器添加了一个处理程序。在Python的早期版本中,由于basicConfig()
中存在线程安全缺陷,这可能(在极少数情况下)导致将处理程序多次添加到根记录器,从而导致同一事件的多条消息
logging.info('2')
logger.info('3')