本章主要讲了python程序的调试,当程序有BUG或异常的时候,我们如何调试代码找出问题点。其实在本章之前的章节我们做练习的时候都会遇到各种各样的错语和异常,最初当不知道程序哪里出错的情况下不可否认的都使用了print语句进行输出并调试代码。没错print也是调试代码的一种工具,直观简单,但也有缺点,就是调试好后要删除print语句,也是件麻烦事,于是就有了本章介绍的assert(断言),logging(日志)以及各种调试工具的出现。

首先来回顾一下python的异常。

一.python常见的异常类型

异常名称  描述
BaseException 所有异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(通常是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
LookupError 无效数据查询的基类
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告

二.python异常处理

python处理异常的完整语句如下:实际程序中并不是每个语句都要用上,可以组合起来用。

try:
    try_suite
except Exception1,Exception2,...,Argument:
    exception_suite
......   #other exception block
else:
    no_exceptions_detected_suite
finally:
    always_execute_suite

具体用法请参见:

python2:http://www.runoob.com/python/python-exceptions.html

python3:http://www.runoob.com/python3/python3-errors-execptions.html

三.抛出异常

抛出异常使用raise语句。

语法:raise Exception(‘出错信息的字符串’)

此语句直接在交互模式下运行则会直接报错并返回Exception函数中的字符串。一般情况下raise语句用在函数中,try和except语句在调用该函数的代码中,在except语句中接收exception函数作为参数。

except Exception as err:

print(‘An exception happened:’ + str(err)

四.traceback模块

使用traceback模块可以跟踪异常并得到更祥细的出错信息,其实程序如果没有进行异常处理但是确实有异常存在的时候,从屏幕输出的信息来看,我们都会看很祥细的出错信息,包括哪一行出错,是什么错误等等,这应该就是traceback模块返回的信息,只是python本身帮我们抛出了异常。

在交互模式下,先导入traceback模块,通过help()就可以查看traceback的帮助信息。

import traceback

help(traceback)

2个常用函数

format_exc()返回字符串,print_exc()则直接给打印出来

五.断言assert

使用assert语句检查,如果失败就抛出异常

语法:

assert 条件,’异常信息’

例如:

In [16]: p = 1

In [17]: assert p==0,'error'
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-17-11c0bd0cc9d4> in <module>()
----> 1 assert p==0,'error'

AssertionError: error

六.logging日志模块

Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,共有5个级别

级别 日志函数 描述
DEBUG logging.debug() 最低级别,用于小细节。通常只有在诊断问题时,你才会关心这些信息
INFO logging.info() 用于记录程序中一般的事件信息,或确认一切工作正常
WARNING logging.warning() 用于表示可能的问题,它不阻止程序的工作,但将来可能会
ERROR logging.error() 用于记录错误,它导致程序做某事失败
CRITICAL logging.critical() 最高级别。用于表示致命的错误,它导致或将要导致程序完全停止

使用语法:

In [18]: import logging

In [19]: logging.basicConfig(level=logging.debug,format='%(asctime)s - %(levelname)s - %(message)s')

In [20]: logging.debug('some debugging details')
2017-04-28 23:36:39,795 - DEBUG - some debugging details

format,定义了最终log信息的顺序,结构和内容。

%(name)s Logger的名字
%(levelname)s 文本形式的日志级别
%(message)s 用户输出的消息
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(levelno)s 数字形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s  调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有

禁用日志

In [21]: logging.disable(logging.debug)

将日志写入文件

In [22]: logging.basicConfig(filename='mylog.txt',level=logging.debug,format='%(asctime)s - %(levelname)s - %(message)s')

7.实践项目参考答案

#!/usr/bin/env python3.4
# debug.py
# create by mfyang 2017-04-28
import random
import logging
logging.basicConfig(level=logging.DEBUG,format=' %(asctime)s - %(levelname)s -%(message)s')
#logging.disable(logging.DEBUG)
logging.debug('start of program')
guess = ''
while guess not in ('heads','tails'):
    print('Guess the coin toss! Enter heads or tails:')
    guess = input()
    logging.debug('you input is:' + str(guess))
toss = random.randint(0,1)
coinresult = ''
if toss == 0:
    coinresult = 'tails'
if toss == 1:
    coinresult = 'heads'
logging.debug('toss is(0 is tails 1 is heads):' + coinresult)
if coinresult == guess:
    print('you got it!')
else:
    print('Nope! Guess again')
    guess = input()
    logging.debug('you input is:' + str(guess))
    if coinresult == guess:
        print('You got it!')
    else:
        print('Nope. You are really bad at this game.')
logging.debug('end of debug')

python编程快速上手之第10章实践项目参考答案的更多相关文章

  1. python编程快速上手之第9章实践项目参考答案

    本章介介绍了shutil,zipfile模块的使用,我们先来认识一下这2个模块吧. 一.shutil模块 shutil模块主要用于对文件或文件夹进行处理,包括:复制,移动,改名和删除文件,在shuti ...

  2. python编程快速上手之第8章实践项目参考答案

    第8章实践项目之疯狂填词 创建一个一个疯狂填词(Mad Libs),程序,它将读入文本文件,并让用户在该文本文件中出现 ADJECTIVE,NOUN,VERB等单词的地方,加上他们自己的文本. 首先准 ...

  3. python编程快速上手之第5章实践项目参考答案

    #!/usr/bin/env python3.5 # coding:utf-8 # 5.6.1 # 好玩游戏的物品清单 # 给定一个字典,包含物品名称和数量,并打印出数量对应的物品 dict_stuf ...

  4. python编程快速上手之第3章实践项目参考答案

    1 #!/usr/bin/env python 2 # coding:utf-8 3 # write by mfyang 4 # collatz.py 5 # 从用户读入一个值,并判断这个值是不是一个 ...

  5. python编程快速上手之第6章实践项目参考答案

    #!/usr/bin/env python3.5 2 #coding:utf-8 3 # 4 # 这个项目主要目的是字符串的处理,简单格式化输出 5 tableData = [['apples','o ...

  6. python编程快速上手之第4章实践项目参考答案

    #!/usr/bin/env python3.5 # coding:utf-8 # 假定有一个列表,编写函数以一个列表值作为参数,返回一个字条串 # 该字符串包含所有表项,之间以逗号和空格分隔,并在最 ...

  7. python编程快速上手之第7章实践项目参考答案

    #!/usr/bin/env python3.5 #coding:utf-8 import re # 7.18.1 # 强口令检测 # 写一个函数,使用正则表达式,确保传入的口令字符串是强口令 # 长 ...

  8. Python 编程快速上手 第十四章 处理 CSV 文件和 JSON 数据

    前言 这一章分为两个部分,处理 CSV 格式的数据和处理 JSON 格式个数据. 处理 CSV 理解 csv csv 的每一行代表了电子表格中的每一行,每个逗号分开两个单元格csv 的内容全部为文本, ...

  9. Python 编程快速上手 第十五章 保持时间,计划任务和启动程序

    前言 这一章节的主要内容是: 处理时间类型的数据(使用python 的两个模块: time 和 datetime 来处理) 创建多个线程 (使用 threading 模块来创建多个线程) 进行多个进程 ...

随机推荐

  1. Commons-lang API介绍

    4.1 Commons-lang API介绍 4.1.1 StringUtils 4.1.2 StringEscapeUtils 4.1.3 ArrayUtils 4.1.4 DateUtils 4. ...

  2. Lua学习(2)——表达式

    1. lua算术操作符lua支持的算数操作符: + - * /除 ^指数 %取模 -符号 2. lua关系操作符 <小于 >大于 <= >= == ~=不等于 3. 逻辑操作符 ...

  3. MySQL优化总结,百万级数据库优化方案

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  4. springcloud(九):配置中心和消息总线(配置中心终结版)

    我们在springcloud(七):配置中心svn示例和refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用webhook的机制每次提交代码发送请求来刷新客户端 ...

  5. shell中如何进行算术运算

    A=3 B=6 1.let算术运算表达式 let C=$A+$B2.$[算术运算表达式] C=$[$A+$B] 3.$(()) C=$(($A+$NB))

  6. jsonp跨域再谈

    昨天面试雷锋网,问到了jsonp跨域的问题,其实这个问题之前就会的,没有多大的深入,记得有一个名词在跨域中出现,就是同源机制, JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在J ...

  7. Azure 基础:Table storage

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table.其中的 Table 就是本文的主角 Azure Tabl ...

  8. javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)

    javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置.大小.粗度.翻转.平滑等操作 javaCV图像处理之2:实时视频添加图片水 ...

  9. HTML中那些不常用标签

    先思考一个问题:为什么H5里面又多了那么多看似没用的标签? 我们知道,<div>能干百分之99的标签能干的事,而标签的主要作用是用来包裹内容,只要把基本内容都包含进去不就好了??胡闹!不带 ...

  10. cms基本概念(dedecms,phpcms)

    1.什么是cms? cms是"Content Management System"的缩写,意为"内容管理系统". 内容管理系统是企业信息化建设和电子政务的新宠, ...