Python编程让繁琐的工作自动化(10)-调试

程序员的笑话:编码占了编程工作量的90%,调试占了另外的90%。
代码出问题很正常,有一些好的工具和技巧可以确定你的代码在做什么,以及哪出了问题。首先,要查看日志和断言,其次要学习如何使用调试器。

抛出异常

#直接抛出异常对象,会引起程序崩溃
>>>raise Exception('this is the erro message.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: this is the error message.
#利用try和except处理异常信息
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)) 
#以下为输出
****
*  *
*  *
****
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遇到错误,会生成一些错误信息,称为‘反向跟踪’。反向跟踪包含了出错消息、导致该错误的代码行号,以及导致该错误的函数调用的序列。这个序列称为‘调用栈’。

def bacon():
    raise Exception('Symbol must be a single character string.')
def spam():
    bacon()
spam()
#输出如下:
Traceback (most recent call last):
  File "1.py", line 5, in <module>
    spam()
  File "1.py", line 4, in spam
    bacon()
  File "1.py", line 2, in bacon
    raise Exception('Symbol must be a single character string.')
Exception: Symbol must be a single character string.
#通过从下往上看,就能依次找出错误的位置,这就是调用栈的作用
#如果希望得到异常的反向跟踪的信息,但也希望except语句能够优雅地处理该异常,可以调用traceback.format_exc()
import traceback
try:
    raise Exception('This is the error message.')
except:
    errorFile = open('errorInfo.txt', 'w')
    errorFile.wirte(traceback.format_exc())
    errorFile.close()
    print('The traceback info was written to errorInfo.txt.')
#输出
116
The traceback info was written to errorInfo.txt

断言

断言就是对语句做检查,来确保代码按照逻辑运行,如果检查失败,说明代码没有按照预想的发展就会出错。
在日常英语中,assert语句是说:我断言这个条件为真,如果不为真,程序中什么地方就有个缺陷。和异常不一样,代码不能用try和except来处理assert语句。如果assert失败,则应该马上崩溃。这样可以减少为了寻找出错的代码而要检查的代码量。

语法:
assert 要判断的语句,判断失败要显示的字符串

podBayDoorStatus = 'open'
assert podDoorStatus=='open', 'The pod bay doors need to be "open".'
podBayDoorStatus = 'I \'m sorry, dave.'
assert podDoorStatus=='open', 'The pod bay doors need to be "open".'
#输出
Traceback (most recent call last):
  File "1.py", line 2, in <module>
    assert podDoorStatus=='open', 'The pod bay doors need to be "open".'
NameError: name 'podDoorStatus' is not defined

在运行python时传入-O选项可以禁用断言。完成了程序编写和测试后,如果不希望检查,可以禁用。断言是针对开发而不是最终产品的。

日志

记日志可以理解程序中发生的事情以及事情发生的顺序。python的logging模块使得你可以创建自定义的消息记录。

不要用print调试,因为调试完成后你需要花很多时间注释或者清除掉print语句,甚至会误删除。而利用日志时,只需要在添加logging.disable(logging.CRITICAL)就可以禁用。日志消息是给程序员看的,而不是给用户的。

日志级别

级别日志函数描述
DEBUGlogging.debug()最低级别,用于小细节,通常只有在诊断问题时才关心
INFOlogging.dinfo()用于记录程序中一般事件的信息,或确认一切工作正常
WARNINGlogging.warning()用于表示可能的问题,不会阻止程序工作,但将来可能会
ERRORlogging.error()用于记录错误,它导致程序做某事失败
CRITICALlogging.critical()最高级别,用于表示致命的错误,它导致或将要导致程序弯曲停止工作

日志消息作为字符串传递给这些函数,日志级别是一种建议,最终由你来决定日志消息属于哪一种类型

import logging
#level控制显示的级别,将logging.DEBUG换成logging.ERROR,将只显示ERROR和CRITICAL消息,跳过其他消息。
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
#禁用日志会禁用该代码后面的同级别和更低的级别的消息。
#logging.disable(logging.ERROR)
>>> logging.debug('Some debugging details.')
 2019-03-03 13:14:10,764 - DEBUG - Some debugging details.
>>> logging.info('the logging module is working.')
 2019-03-03 13:14:34,788 - INFO - the logging module is working.
>>> logging.warning('an error message is about to be logged.')
 2019-03-03 13:15:04,268 - WARNING - an error message is about to be logged.
>>> logging.error('an error has accured.')
 2019-03-03 13:15:21,035 - ERROR - an error has accured.
>>> logging.critical('the program is unable to recover!')
 2019-03-03 13:15:46,292 - CRITICAL - the program is unable to recover!
#将日志记录到文件,只需要添加关键字参数即可
logging.basicConfig(filename='mylogging.txt',level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')

调试器

IDLE的调试器和其他编译器的功能差不多,这里不再赘述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值