CH10调试(异常 断言)--python快速编程

抛出异常

  • 抛出异常使用raise语句 raise语句包含以下部分:
  • raise关键字
  • 对Exception函数的调用
  • 传递给Exception函数的字符串 包含有用的出错信息
>>> raise Exception('This is the error message.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: This is the error message.

如果没有try和except语句覆盖抛出异常的raise语句 程序会崩溃报错

#! /usr/bin/python3
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),('0',20,5),('x',1,3),('ZZ',3,3)):
   try:
     boxPrint(sym,w,h)
   except Exception as err:
     print('An exception happened: '+ str(err))
[root@izwz9eitqs320brxl6owssz ~]# ./boxPrint.py 
****
*  *
*  *
****
00000000000000000000
0                  0
0                  0
0                  0
00000000000000000000
An exception happened: Width must be greater than 2.
An exception happened: Symbol must be a single character string.

取得反向跟踪的字符串

python遇到错误 会生成一些错误信息,称为反向追踪
只要抛出的异常没有被处理,Python就会显示反向跟踪 也可以调用traceback.format_exc(),得到它的字符串形式。

>>> 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.')
... 
111
The traceback info was written to errorInfo.txt.
>>> 

断言

assert是一个心智正常的检查,确保代码没有做什么明显错误的事情,如果检查失败 会抛出异常。

  • assert关键字
  • 条件(求值为True或False的表达式)
  • 逗号
  • 当条件为False的字符串
>>> podBayDoorStatus = '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 "<stdin>", line 1, in <module>
AssertionError: The pod bay doors need to be "open"

模拟交通等使用断言:
assert ‘red’ in stoplight.values(),’Neither light is red!’+str(stoplight)

>>> market_2nd = {'ns':'green','ew':'red'}
>>> mission_16th = {'ns':'red','ew':'green'}
>>> def switchLights(stoplight):
...   for key in stoplight.keys():
...     if stoplight[key] == 'green':
...        stoplight[key] = 'yellow'
...     elif stoplight[key] == 'yellow':
...        stoplight[key] = 'red'
...     elif stoplight[key] == 'red':
...        stoplight[key] = 'green'
...   assert 'red' in stoplight.values(),'Neither light is red!'+str(stoplight)
... 
>>> 
>>> switchLights(market_2nd)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in switchLights
AssertionError: Neither light is red!{'ns': 'yellow', 'ew': 'green'}

日志

日志消息将描述程序执行何时到达日志函数调用,并列出你指定的任何变量当时的值。
另一方面 缺失的日志信息表明有一部分代码被跳过 从未执行。

>>> import logging
>>> logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
>>> logging.debug('Start of program')
 2018-08-17 16:53:34,258 - DEBUG - Start of program
>>> def factorial(n):
...    logging.debug('Start of factorial(%s%%)' % (n))
...    total = 1
...    for i in range(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))
 2018-08-17 17:04:07,412 - DEBUG - Start of factorial(5%)
 2018-08-17 17:04:07,413 - DEBUG - i is0, total is 0
 2018-08-17 17:04:07,413 - DEBUG - i is1, total is 0
 2018-08-17 17:04:07,413 - DEBUG - i is2, total is 0
 2018-08-17 17:04:07,413 - DEBUG - i is3, total is 0
 2018-08-17 17:04:07,413 - DEBUG - i is4, total is 0
 2018-08-17 17:04:07,413 - DEBUG - i is5, total is 0
 2018-08-17 17:04:07,413 - DEBUG - End of factorial(5%)
0
>>> logging.debug('End of program')
 2018-08-17 17:05:33,714 - DEBUG - End of program
  • 将for i in range (n+1): 改为 for i in range (1,n+1)
#! /usr/bin/python3
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')
[root@izwz9eitqs320brxl6owssz ~]# ./factorialLog.py 
 2018-08-17 17:13:13,890 - DEBUG - Start of program
 2018-08-17 17:13:13,890 - DEBUG - Start of factorial(5%)
 2018-08-17 17:13:13,890 - DEBUG - i is1, total is 1
 2018-08-17 17:13:13,890 - DEBUG - i is2, total is 2
 2018-08-17 17:13:13,890 - DEBUG - i is3, total is 6
 2018-08-17 17:13:13,890 - DEBUG - i is4, total is 24
 2018-08-17 17:13:13,890 - DEBUG - i is5, total is 120
 2018-08-17 17:13:13,890 - DEBUG - End of factorial(5%)
120
 2018-08-17 17:13:13,890 - DEBUG - End of program
  • 不要用print()调试
    日志消息是给程序员的 不是给用户的
  • 日志级别:
级别 日志函数 描述
DEBUG logging.debug() 最低级别。用于小细节。通常只有在诊断问题时,才会关系这些消息
INFO logging.info() 用于记录程序中一般事件的信息 确认一切工作正常
WARNING logging.warning() 用于表示可能的问题 不会阻止程序的工作 但将来可能会
ERROR logging.error() 用于记录错误,导致程序做某事失败
CRITICAL logging.critical() 最高级别 用于表示致命的错误,导致或将要导致程序完全停止工作
>>> import logging
logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
>>> logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
>>> logging.debug('Some debugging details')
 2018-08-17 17:28:40,344 - DEBUG - Some debugging details
>>> logging.info('The logging moudule is working')
 2018-08-17 17:28:40,345 - INFO - The logging moudule is working
>>> logging.warning('An error message is about to be logged')
 2018-08-17 17:28:40,410 - WARNING - An error message is about to be logged
>>> logging.error('An error has occured')
 2018-08-17 17:28:40,425 - ERROR - An error has occured
>>> logging.critical('The program is unable to recover!')
 2018-08-17 17:28:42,396 - CRITICAL - The program is unable to recover!

Debug是最低级别 可以调试为ERROR级别 跳过DEBUG INFO WARNING消息。
- logging.disable()函数禁用了这些消息 可以向logging(logging.CRITICAL).例如在交互式环境中输入以下代码:

>>> logging.disable(logging.CRITICAL)
>>> logging.critical('Critical error!Critical error!')
>>> logging.error('ERROR,ERROR!')
  • 添加到文件中去
>>> import logging
>>> logging.basicConfig(filename = 'myProgramLog.txt',level=logging.DEBUG,format=' %(asctime)s - %(levelname)s - %(message)s')
>>> logging.debug('Some debugging details')
>>> logging.info('The logging moudule is working')
>>> logging.warning('An error message is about to be logged')
>>> logging.error('An error has occured')
>>> logging.critical('The program is unable to recover!')
>>> exit()
[root@izwz9eitqs320brxl6owssz ~]# cat myProgramLog.txt 
 2018-08-17 17:36:43,848 - DEBUG - Some debugging details
 2018-08-17 17:36:43,858 - INFO - The logging moudule is working
 2018-08-17 17:36:43,876 - WARNING - An error message is about to be logged
 2018-08-17 17:36:43,890 - ERROR - An error has occured
 2018-08-17 17:36:46,374 - CRITICAL - The program is unable to recover!

调试

IDLE调速器
进行测试

#!python3
first = input('Enter the first number to add:')
second = input('Enter the second number to add:')
third  = input('Enter the third number to add:')
print('The sum is '+first + second + third)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/ichglauben/article/details/81780486
今日推荐