在程序运行过程中,总会遇到各种各样的错误。

有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的。

有的错误是用户输入造成的,比如让用户输入email地址,结果得到一个空字符串,这种错误可以通过检查用户输入来做相应的处理。

还有一类错误是完全无法在程序运行过程中预测的,比如写入文件的时候,磁盘满了,写不进去了,或者从网络抓取数据,网络突然断掉了。这类错误也称为异常,在程序中通常是必须处理的,否则,程序会因为各种问题终止并退出。

错误处理

try...except...finally

当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。

 #!/usr/bin/python3

 try:
r = 10 / 0
print ('result:',r)
except ZeroDivisionError as e:
print ('除数不能为零 ',e)
finally:
print ('--------')
print ('END')

如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句:

 #!/usr/bin/python3

 try:
r = 10 / int('')
print ('result:',r)
except ZeroDivisionError as e:
print ('除数不能为零 ', e)
except ValueError as e: #int()可能抛出ValueError
print ('ValueError', e)
else:
print ('No Error!')
finally:
print ('--------')
print ('END')

Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。

常见的错误类型和继承关系  https://docs.python.org/3/library/exceptions.html#exception-hierarchy

使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo()foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理:

 #!/usr/bin/python3

 def foo(s):
return 10 / s def bar(s):
return foo(s)*2 def main():
try:
bar('')
except Exception as e:
print ('Error', e)
finally:
print ('---------------') main()

Python中的异常分类

 NameError    #尝试访问一个未声明的变量(没有初始化)
ZeroDivisionError #除数为零
SyntaxError #解释器语法错误,唯一不是在运行时发生的异常,在编译时发生,它代表Python代码中有一个不正确的结构
IndexError #请求的索引超出序列范围
KeyError #请求一个不存在的字典键
IOError #输入输出错误:(1)打开一个不存在的文件(2)文件写入时,操作和模式不匹配(3)权限问题导致
TypeError #类型错误,如'2'+2,类型不相同不能相加
AttributeError #尝试访问未知的对象属性,即对象根本没有定义这一属性却尝试访问它
StopIteration #迭代器没有更多的值
RuntimeError #一般的运行时错误
SystemError #一般的解释器系统错误
ValueError #传入无效的参数

调用栈

如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。

 #!/usr/bin/python3

 def foo(s):
return 10 / int(s) def bar(s):
return foo(s)*2 def main():
bar('') main()

可以看到,问题的源头追溯到第四行代码,第四行代码,除数不能为零

记录错误

捕获错误,打印错误堆栈,同时让程序继续执行

 #!/usr/bin/python3

 import logging

 def foo(s):
return 10 / int(s) def bar(s):
return foo(s)*2 def main():
try:
bar('')
except Exception as e:
logging.exception(e) main()
print('END')

同样是出错,但程序打印完错误信息后会继续执行,并正常退出:

抛出错误

如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例:

 #!/usr/bin/python3

 class FooError(ValueError):   #选择好继承关系
pass def foo(s):
n = int(s)
if n == 0:
raise FooError('无效的值:%s' % s)
return 10 / n foo('')

只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如ValueErrorTypeError),尽量使用Python内置的错误类型。

调试

程序能一次写完并正常运行的概率很小,总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。

断言   assert

把可能有问题的变量打印出来看看

 #!/usr/bin/python3

 def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n def main():
foo('') main()

assert的意思是,表达式 n != 0应该是True,True的话继续执行,否则,根据程序运行的逻辑,后面的代码肯定会出错。

如果断言失败,assert语句本身就会抛出AssertionError

logging

assert比,logging不会抛出错误,而且可以输出到文件,可指定记录信息的级别(低到高:debug  info  warning  error)当指定 level = WARNING后 debug和info就不起作用,即可以输出不同级别的信息

 #!/usr/bin/python3

 import logging
logging.basicConfig(level = logging.INFO) s = ''
n = int(s)
logging.info('n = %d' % n)
print (10 / n)

pdb

-m pdb  让程序以单步方式运行,可以随时查看运行状态。

 #!/usr/bin/python3

 s = ''
n = int(s)
print (10 / n)

l  查看代码  n  单步  p 变量名    查看变量  q结束调试

python错误和调试的更多相关文章

  1. Python错误、调试和测试

    try: print('try...') r = 10 / int('a') print('result:', r) except ValueError as e: print('ValueError ...

  2. python 错误、调试和测试

    在程序运行过程中,总会遇到各种各样的错误. 有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的. 有的错误是用户输入造成的,比如让用 ...

  3. python错误处理/调试/单元测试/文档测试

    一.错误处理 1.错误处理 try: ... except Exception1: ... except Exception2: ... finally: ... 如果在try中发生错误,那么exce ...

  4. python 错误、调试、单元测试、文档测试

    错误分为程序的错误和由用户错误的输入引起的错误,此外还有因为各种各样意外的情况导致的错误,比如在磁盘满的时候写入.从网络爬取东西的时候,网络断了.这类错误称为异常 错误处理 参考链接:https:// ...

  5. python错误、调试、测试

    1.错误, Python内置的try...except...finally用来处理错误十分方便.出错时,会分析错误信息并定位错误发生的代码位置才是最关键的. 程序也可以主动抛出错误,让调用者来处理相应 ...

  6. Python:笔记(5)——错误、调试和测试

    Python:笔记(5)——错误.调试和测试 错误处理 1.TRY语句 这个和Java中的语法是及其相似的,catach换成except. 说明:同样,不管有没有错误,fianlly都会执行的! 补充 ...

  7. python: 错误处理try详解 ,traceback调用栈, 调试(logging)

    摘录:https://www.liaoxuefeng.com/wiki/1016959663602400/1017598873256736 错误处理 调试 错误处理 高级语言都会使用内置的一套try. ...

  8. [转] python程序的调试方法

    qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...

  9. 004-python面向对象,错误,调试和测试

    ---恢复内容开始--- 1.面向对象 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

随机推荐

  1. PC逆向之代码还原技术,第四讲汇编中减法的代码还原

    目录 PC逆向之代码还原技术,第四讲汇编中减法的代码还原 一丶汇编简介 二丶高级代码对应汇编观看. 1.代码还原解析: 三丶根据高级代码IDA反汇编的完整代码 四丶知识总结 PC逆向之代码还原技术,第 ...

  2. ES6躬行记(20)——类

    ES6正式将类(Class)的概念在语法层面标准化,今后不必再用构造函数模拟类的行为.而ES6引入的类本质上只是个语法糖(即代码更为简洁.语义更为清晰),其大部分功能(例如继承.封装和复用等)均可在E ...

  3. 微服务浪潮中,程序猿如何让自己 Be Cloud Native

    前言 CNCF 与 Cloud Native 这两个技术词汇最近频频走进了程序员的视野,一切和他能搭上边的软件意味着标准.开放.时尚,也更能俘获技术哥哥们的心:这篇文章不想去带大家重温这个词汇后面的软 ...

  4. 执行对象Statement、PreparedStatement和CallableStatement详解 JDBC简介(五)

    执行对象是SQL的执行者,SQL是“安排好的任务”,执行对象就是“实际工作的人”. 执行对象有三种: Statement.PreparedStatement和CallableStatement,他们都 ...

  5. spring boot(四) 多数据源

    前言 前一篇中我们使用spring boot+mybatis创建了单一数据源,其中单一数据源不需要我们自己手动创建,spring boot自动配置在程序启动时会替我们创建好数据源. 准备工作 appl ...

  6. Docker容器监控(十)--技术流ken

    docker自带的监控命令 docker自带了三个监控命令即ps, top, stats ps docker ps 可以帮助我们很快的了解当前正在运行的容器 -a:会显示已经停掉的容器 [root@h ...

  7. 在ASP.NET MVC 项目中 使用 echarts 画统计图

    echarts 官方地址:http://echarts.baidu.com/ 一.根据图中的数据怎么从数据库中获取并组装成对应格式: 从数据库中获取对应数据,然后在项目中引用Newtonsoft.Js ...

  8. mybatis_16逆向工程

    简介 简单点说,就是通过数据库中的单表,自动生成java代码. Mybatis官方提供了逆向工程 可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类) 企业开 ...

  9. linux系统管理--top命令

    这些日子,运维公司三台服务器,一个小伙伴貌似对top命令不太感冒,我告诉他去百度(不懂谷歌百度的程序员不是好厨师),然后突然发现也许我自己该整理一下相关的东西了 top命令是Linux下常用的性能分析 ...

  10. Ext中setVersion和getVersion

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...