赞
踩
一般的小代码,初学者可能会采取在适当的地方添加print()方法输出信息来进行代码的检查和调试,但是如果代码比较多,print()方法在调试完成后需要将所有的print()代码都注释或者删除以使得调试输出信息不再输出,这对于大代码非常不方便。因此最好不要养成使用print()语句调试的习惯,一开始就学习使用logging模块debug方法来调试代码。
python系统自带logging模块可以实现对代码的运行追踪的日志记录功能,提供了便捷的代码bug追踪机制,不仅可以将日志打印出来,还可以将日志保存为文档,便于保存与查看。开发人员可以对他们的代码添加日志调用,借此来指示某事件的发生。一个事件通过一些包含变量数据的描述信息来描述(比如:每个事件发生时的数据都是不同的)。logging模块还提供区分事件的重要性的不同级别:
级别 | 级别数值 | 使用时机 |
---|---|---|
DEBUG | 10 | 详细信息,常用于调试。 |
INFO | 20 | 程序正常运行过程中产生的一些信息。 |
WARNING | 30 | 警告用户,虽然程序还在正常工作,但有可能发生错误。 |
ERROR | 40 | 由于更严重的问题,程序已不能执行一些功能了。 |
CRITICAL | 50 | 严重错误,程序已不能继续运行。 |
logging的默认的级别是WARNING,意味着只会追踪该级别及以上的事件,DEBUG和INFO会被忽略,WARING、ERROR和CRITICAL会被记录,除非更改日志配置。
一个简单的将结果输出到控制台的语句为:
import logging
logging.warning('info level') # WARNING:root:info levelb
有多种方法用来处理被跟踪的事件。最简单的方法就是把它们打印到终端控制台上:
import logging
from logging import debug
logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', level = logging.DEBUG)
def func(s):
str1 = 'Loop'
str2 = 'leap'
debug(f's的数据类型为 {type(s)}, {s}')
debug(f'{str1} before you {str2}')
return s/10
if __name__ == '__main__':
func(100)
输出结果为:
DEBUG:func:s的数据类型为 <class 'int'>, 100
DEBUG:func:Loop before you leap
在使用过程中可以直接用logging.debug()来替换print()。如果程序调试好,可以通过修改level来控制debug info的输出, eg:将以下这句的level = logging.DEBUG换为logging.INFO就可以了:
logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', level = logging.INFO)
basicConfig方法中的format定义了日志信息中包含的信息的格式,变量是logging内置的keys:
属性 | 格式 | 描述 |
---|---|---|
asctime | %(asctime)s | 日志产生的时间,默认格式为2003-07-08 16:49:45,896 |
created | %(created)f | time.time()生成的日志创建时间戳 |
funcName | %(funcName)s | 调用日志的函数名 |
levelname | %(levelname)s | 日志级别 (‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’) |
lineno | %(lineno)d | 日志所针对的代码行号(如果可用的话) |
module | %(module)s | 生成日志的模块名 |
message | %(message)s | 具体的日志信息 |
name | %(name)s | 日志调用者 |
我们还可以通过basicConfig方法中的参数设置,将结果输出到文件:
import logging
logging.basicConfig(filename='test.log', level=20)
logging.log(10, '级别为10的一条日志')
logging.log(20, '级别为20的一条日志')
上例中,通过basicConfig方法将日志输出到test.log文件,并且设置只有级别大于等于20的才会写入到该日志文件。也就是说,上例中,第一条级别为10的日志将不会写入到文件。并且,需要注意的是,如果你查看日志文件,如果出现乱码的话,请检查编码方式。
上例中,在basicConfig方法中,级别20也可以这样指定:
logging.basicConfig(filename='test.log', level=logging.INFO)
logging.debug('debug level: 10')
logging.info('info level: 20')
logging.warning('warning level: 30')
logging.error('error level: 40')
logging.critical('critical level: 50')
上例中同样只有级别大于等于20的将会被写入文件test.log。
basicConfig方法还可以指定一下参数:
示例:
import logging
logging.basicConfig(
filename='test.log',
filemode='w',
level=logging.DEBUG,
datefmt='%Y/%m/%d %H:%M:%S',
format='%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(module)s - %(message)s'
)
logging.debug('debug level: 10')
logging.info('info level: 20')
logging.warning('warning level: 30')
logging.error('error level: 40')
logging.critical('critical level: 50')
输出结果为:
2019/05/30 14:38:09 - root - DEBUG - 36 - 日志模块 - debug level: 10
2019/05/30 14:38:09 - root - INFO - 37 - 日志模块 - info level: 20
2019/05/30 14:38:09 - root - WARNING - 38 - 日志模块 - warning level: 30
2019/05/30 14:38:09 - root - ERROR - 39 - 日志模块 - error level: 40
2019/05/30 14:38:09 - root - CRITICAL - 40 - 日志模块 - critical level: 50
需要注意的是,logging.basicConfig只生效一次,比如:
···
import logging
logging.basicConfig(
filename=‘test1.log’,
filemode=‘w’,
level=logging.DEBUG
)
logging.basicConfig(
filename=‘test2.log’,
filemode=‘a’,
level=logging.INFO
)
logging.debug(‘debug level: 10’)
logging.info(‘info level: 20’)
logging.warning(‘warning level: 30’)
logging.error(‘error level: 40’)
logging.critical(‘critical level: 50’)
···
正如上例所示,我们配置了两次basicConfig。但如果运行你会发现,只有第一个配置生效了,第二个配置不会生效。原因是当在第一次配置的时候,logging在内部就会进行配置,第二次再次配置的时候,logging就会认为我已经配置好了,不需要再次配置了。
首先使用logging.getLogger()进行配置,参数为文件名,通过logger.setLevel()设置logger的级别:
import logging
# 配置logger并设置等级为DEBUG
logger = logging.getLogger('logging_debug')
logger.setLevel(logging.DEBUG)
然后使用logging.StreamHandler()方法初始化consoleHandler,通过consoleHandler.setLevel()设置级别:
# 配置控制台Handler并设置等级为DEBUG
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)
再通过logger.addHandler()方法将consoleHandler加入logger,完成logger的配置:
logger.addHandler(consoleHandler)
完整代码:
import logging
# 配置logger并设置等级为DEBUG
logger = logging.getLogger('logging_debug')
logger.setLevel(logging.DEBUG)
# 配置控制台Handler并设置等级为DEBUG
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)
# 将Handler加入logger
logger.addHandler(consoleHandler)
logger.debug('This is a logging.debug')
输出结果:
This is a logging.debug
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。