调试
抛出异常
抛出异常使用raise语句,包括:raise关键字,对Exception函数的调用,传递给Exception函数的字符串
def boxPrint(symbol, width, height):
if len(symbol) != 1:
raise Exception('Symbol must be a single character string.')
if width <= 2:
raise Exception('Width must be greater than 2.')
if height <= 2:
raise Exception('Height must be greater than 2.')
print(symbol * width)
for i in range(height - 2):
print(symbol + (' ' * (width - 2)) + symbol)
print(symbol * width)
for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)):
try:
boxPrint(sym, w, h)
except Exception as err:
print('An exception happened: ' + str(err))
取得反向跟踪的字符串
Python 遇到错误,会产生一些错误信息,称为“反向跟踪”。
例如:
运行
def spam():
bacon()
def bacon():
raise Exception('This is the error message.')
spam()
则会输出
Traceback (most recent call last):
File "errorExample.py", line 7, in <module>
spam()
File "errorExample.py", line 2, in spam
bacon()
File "errorExample.py", line 5, in bacon
raise Exception('This is the error message.')
Exception: This is the error message.
可以调用traceback.format_exc(),得到反向跟踪信息的字符串形式(调用函数需导入traceback模块)
例如,不是让程序在异常发生时就崩溃,可以将反向跟踪信息写入一个日志文件,并让程序继续运行。
在调试程序时可以检查该日志文件。
>>>import traceback
>>>try:
raise Exception('This is the error message.')
except:
errorFile = open('errorInfo.txt', 'w')
errorFile.write(traceback.format_exc())
errorFile.close()
print('The traceback info was written to errorInfo.txt.')
116
The traceback info was written to errorInfo.txt.
write()的返回值是116,表示116个字符写入到文件中。反向跟踪文本被写入到==‘errorInfo.txt’==中
断言
“断言”检查代码没有做什么明显错误的事。(主要针对程序员在代码中所出的错误)
如果检查失败,就会抛出异常。
该检查主要由assert语句执行,包括:
1.assert关键字
2.条件(即求值为True或False的表达式)
3.逗号
4.当条件为False时显示的字符串
例如:
>>> podBayDoorStatus = 'open'
>>> assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".'
>>> podBayDoorStatus = 'I\'m sorry, Dave. I\'m afraid I can't do that.''
>>> assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".'
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".'
AssertionError: The pod bay doors need to be "open".
禁用断言
在运行python时传入-O选项,可以禁用断言。
日志
python的logging模块可以容易的创建自定义的消息记录。这些日志消息将描述程序执行到何时到达日志函数调用,并列出指定的变量的当时值。
缺失日志信息表示有一部分代码被跳过,未执行。
启用logging模块,在程序运行时将日志信息显示在屏幕上,需要进行配置
例如:
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s
- %(message)s')
python记录事件的日志时,会创建一个LogRecord对象,保存关于该事件的信息。
logging模块的函数可以让你指定想看到的这个LogRecord对象的细节,以及希望的细节展示方式。
下面是一个计算阶乘的例子
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s
- %(message)s')
logging.debug('Start of program')
def factorial(n):
logging.debug('Start of factorial(%s%%)' % (n))
total = 1
for i in range(1,n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s%%)' % (n))
return total
print(factorial(5))
logging.debug('End of program')
打印日志信息时,使用logging.debug()函数,该函数将调用basicConfig(),打印一行信息。
信息的格式是在basicConfig()函数中指定的,并且包含传递给debug()的消息。
输出看起来像这样
2015-05-23 17:13:40,650 - DEBUG - Start of program
2015-05-23 17:13:40,651 - DEBUG - Start of factorial(5)
2015-05-23 17:13:40,651 - DEBUG - i is 1, total is 1
2015-05-23 17:13:40,654 - DEBUG - i is 2, total is 2
2015-05-23 17:13:40,656 - DEBUG - i is 3, total is 6
2015-05-23 17:13:40,659 - DEBUG - i is 4, total is 24
2015-05-23 17:13:40,661 - DEBUG - i is 5, total is 120
2015-05-23 17:13:40,661 - DEBUG - End of factorial(5)
120
2015-05-23 17:13:40,666 - DEBUG - End of program
禁用日志
避免使用print()来调试
logging.disable//==logging.CRITICAL(最高级别禁用)==禁用日志
向logging.disable()传入日志级别,就会禁止该级别和更低级别的所有日志消息
演示:
>>> import logging
>>> logging.basicConfig(level=logging.INFO, format=' %(asctime)s -
%(levelname)s - %(message)s')
>>> logging.critical('Critical error! Critical error!')
2015-05-22 11:10:48,054 - CRITICAL - Critical error! Critical error!
>>> logging.disable(logging.CRITICAL)
>>> logging.critical('Critical error! Critical error!')
>>> logging.error('Error! Error!')
logging.disable()将禁用它之后的所有消息。
所以一般将它写在接近import logging的位置,方便在有需要时注释掉它。
日志级别
日志级别提供了一种方式,按重要性对日志消息进行分类
5个日志级别如图,从最不重要到最重要,利用不同的日志函数,消息可以按某个级别记入日志
演示:
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s -
%(levelname)s - %(message)s')
>>> logging.debug('Some debugging details.')
2015-05-18 19:04:26,901 - DEBUG - Some debugging details.
>>> logging.info('The logging module is working.')
2015-05-18 19:04:35,569 - INFO - The logging module is working.
>>> logging.warning('An error message is about to be logged.')
2015-05-18 19:04:56,843 - WARNING - An error message is about to be logged.
>>> logging.error('An error has occurred.')
2015-05-18 19:05:07,737 - ERROR - An error has occurred.
>>> logging.critical('The program is unable to recover!')
2015-05-18 19:05:45,794 - CRITICAL - The program is unable to recover!
将日志记录到文件
例如:
import logging
logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format='
%(asctime)s - %(levelname)s - %(message)s')