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

有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为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. 导航页-LeetCode专题-Python实现

    LeetCode专题-Python实现之第1题:Two Sum LeetCode专题-Python实现之第7题:Reverse Integer LeetCode专题-Python实现之第9题:Pali ...

  2. Python迭代和解析(2):迭代初探

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 在Python中支持两种循环格式:while和for.这两种循环的类型不 ...

  3. celery4+django2定时任务

    网上有很多celery + django实现定时任务的教程,不过它们大多数是基于djcelery + celery3的: 或者是使用django_celery_beat配置较为繁琐的. 显然简洁而高效 ...

  4. WPF xaml中列表依赖属性的定义

    列表内容属性 如上图,是一个列表标题排序控件,我们需要定义一个标题列表,从而让调用方可以自由的设置标题信息. 在自定义控件时,会遇到列表依赖属性,那么该如何定义呢? 下面是错误的定义方式: /// & ...

  5. 轻松搞定RocketMQ入门

    RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅机制 亿级消息堆积能力 RocketMQ网络 ...

  6. Android项目刮刮奖详解(三)

    Android项目刮刮奖详解(二) 前言 上一期我们已经实现了一个简易的刮刮卡功能,这一期我们来将其完善一下 目标 将刮刮奖的宽高改为合适高度 将刮刮奖位置居中 将信息层的图片换成文字(重点) 实现 ...

  7. Win10系统给文件夹添加备注

    在Win10系统中,相信大多用户都没有看到过文件或者是文件夹上有备注信息.下面给大家分享下在Win10系统中给文件夹或文件添加备注的方法.在添加备注之前,首先我们要在需要显示备注的文件夹中显示&quo ...

  8. 20, CSS 定义选择器

    1. ID 与类 2. 层叠 3. 分组 4. 继承 5. 上下文选择器 6. 子类选择器 7. 其他选择器 8. 结构与注释 20.1 ID 与类 选择器是用于控制页面设计的样式.即 ID 选择器何 ...

  9. Spring boot入门(二):Spring boot集成MySql,Mybatis和PageHelper插件

    上一篇文章,写了如何搭建一个简单的Spring boot项目,本篇是接着上一篇文章写得:Spring boot入门:快速搭建Spring boot项目(一),主要是spring boot集成mybat ...

  10. [伟哥开源项目基金会](https://github.com/AspNetCoreFoundation)

    伟哥开源项目基金会 GitHub_base=> 伟哥开源项目基金会 该项目作者为伟哥,GitHub地址:https://github.com/amh1979: 该项目维护者为鸟窝,GitHub地 ...