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

 

本章主要讲了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编程快速上手之第9章实践项目参考答案


下一篇:React 实践项目 (五)