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

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

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

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

Python内置了一套异常处理机制,来帮助我们进行错误处理。

此外,我们也需要跟踪程序的执行,查看变量的值是否正确,这个过程称为调试。Python的pdb可以让我们以单步方式执行代码。

最后,编写测试也很重要。有了良好的测试,就可以在程序修改后反复运行,确保程序输出符合我们编写的测试。

一、错误处理

1、语法错误

python的语法错误或者称之为解析错:SyntaxError: invalid syntax

2、异常

python程序的语法是正确的,但在运行期间检测到的错误称为异常,大多数的异常都不会被程序处理,都以错误信息的形式展现出来;常见的类型有: ZeroDivisionError,NameError 和 TypeError。

 1 异常处理:
 2 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
 3 IOError 输入/输出异常;基本上是无法打开文件
 4 ImportError 无法引入模块或包;基本上是路径问题或名称错误
 5 IndentationError 语法错误(的子类) ;代码没有正确对齐
 6 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
 7 KeyError 试图访问字典里不存在的键
 8 KeyboardInterrupt Ctrl+C被按下
 9 NameError 使用一个还未被赋予对象的变量
10 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
11 TypeError 传入对象类型与要求的不符合
12 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
13 导致你以为正在访问它
14 ValueError 传入一个调用者不期望的值,即使值的类型是正确的

3、异常处理

高级语言通常都内置了一套try...except...finally...的错误处理机制,python也不例外。

异常处理的三种方式:try:print(a)
except:print('Error')
#try...except...
try:print(a)
except TypeError as e:print(e)
except NameError as e:print(e)
#try...except NAME_ERROR as E
try:print(a)
except NameError as e:print(e)
except:print('Error')
finally:print('hello')
#finally下的是,不管程序是否错误都执行的代码块

try:# 主代码块pass
except KeyError,e:# 异常时,执行该块pass
else:# 主代码块执行完,执行该块pass
finally:# 无论异常与否,最终执行该块pass

try语句按照如下方式工作;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。

一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。

处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

except (RuntimeError, TypeError, NameError):pass

最后一个except子句可以忽略异常的名称,它将被当作通配符使用。

try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。

try:a = 1print(a)
except NameError as e:print(e)
except:print('Error')
else:print('hello')  #else里的代码块是在try内的代码没有发生错误的时候才执行
finally:print('world')  #finally里的代码块是不管try里的代码是否正确都执行

使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。

4、记录错误

如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。

Python内置的logging模块可以非常容易地记录错误信息:

import logging
def foo(s):return 10 / int(s)
def bar(s):return foo(s) * 2
def main():try:res = bar('0')print(res)except Exception as e:# print(e)logging.exception(e)    #记录错误信息
main()
print('END')

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

5、抛出错误

因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。只有在必要的时候才定义我们自己的错误类型。

捕获错误的目的只是记录一下,便于后续追踪。可以通过raise语句来实现:

try:print(a)
except NameError as e:print(e)raise

raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error还可以把一种类型的错误转化成另一种类型,只要是合理的转换逻辑就可以。

二、调试

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

1、简单直接、粗暴有效的就是用print()把可能有问题的变量打印出来看看

def foo(s):n = int(s)print('>>n = %d' % n)return 10 / n
def main():foo('0')
main()

用print()最大的坏处是将来还得删掉它,想想程序里到处都是print(),运行结果中会包含很多垃圾信息。

2、断言

凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:

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

assert的意思是,表达式 n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错;如果断言失败,assert语句本身就会抛出AssertionError

启动python解释器时可以用-O参数来关闭assert,注意,“-O”时英文字母大写的O;关闭后,我们可以把所有的assert语句当成pass来看。

3、logging

把print()替换为logging是第三种方式,和assert比,logging不会抛出错误,而且可以输出到文件:

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

logging允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,我们就可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。

4、pdb

启动python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。(-m pdb)

输入命令1来查看代码

输入命令n可以单步执行代码

输入命令p+变量名来查看变量

输入命令q结束调试,退出程序

5、pdb.set_trace()

这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点

import pdb
s = '0'
n = int(s)
pdb.set_trace()     #程序运行到这里会暂停进入调试模式
print(10 / n)

运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行

6、IDE [集成开发环境(integrated development environment)]

如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有:
Visual Studio Code:https://code.visualstudio.com/,需要安装Python插件。
PyCharm:http://www.jetbrains.com/pycharm/
另外,Eclipse加上pydev插件也可以调试Python程序。

转载于:https://www.cnblogs.com/renyz/p/11546829.html

python基础之错误、调试(异常处理)相关推荐

  1. Python基础学习笔记:异常处理与断言(assertions)的运用

    python 提供了两个重要的功能来处理 python 程序在运行中出现的异常和错误: 异常处理 断言(assertions) 1.异常处理 捕捉异常可以使用 try/except 语句. try/e ...

  2. Python基础——魔法方法与异常处理

    文章目录 一.魔法方法 1.属性访问 2.描述符 3.定制序列 4.迭代器 5.生成器 二.异常处理 1.异常类型 2.try-except 语句 3.try-finally 语句 4.raise 语 ...

  3. 【python基础】断点调试pdb模块简易使用

    文章目录 前言 代码内使用 命令行使用 前言 断点调试是程序基础,pdb是Python自带的调试器,可以帮助我们在代码中设置断点,并且提供了一些命令来帮助我们在程序执行时进行调试. 代码内使用 以下是 ...

  4. Python 迭代器,错误、异常处理

    迭代器 迭代器可以用来遍历字符串.列表.元组.集合.字典. myString="hello" myIter=iter(myString) ##iter()函数可以获取元素集的一个迭 ...

  5. Python基础知识(六):异常处理

    01_异常的本质_调试核心理念 在实际工作中,我们遇到的情况不可能是非常完美的.比如:你写的某个模块,用户输入不一定符合你的要求;你的程序要打开某个文件,这个文件可能不存在或者文件格式不对;你要读取数 ...

  6. python基础 ---- 使用pyCharm 调试

    debug -- 为了分析程序的异常 单步调试 1.设置断点 2.debug.启动  3.监控变量 转载于:https://www.cnblogs.com/obge/p/10793437.html

  7. python里try和except用法_Python中的错误和异常处理简单操作示例【try-except用法】...

    本文实例讲述了Python中的错误和异常处理操作.分享给大家供大家参考,具体如下: #coding=utf8 print ''''' 程序编译时会检测语法错误. 当检测到一个错误,解释器会引发一个异常 ...

  8. python except用法与作用_Python中关于try-except用法的错误和异常处理详解

    本文实例讲述了Python中的错误和异常处理操作.分享给大家供大家参考,具体如下: #coding=utf8 print ''''' 程序编译时会检测语法错误. 当检测到一个错误,解释器会引发一个异常 ...

  9. python的try和except用法_Python中的错误和异常处理简单操作示例【try-except用法】...

    本文实例讲述了Python中的错误和异常处理操作.分享给大家供大家参考,具体如下: #coding=utf8 print ''''' 程序编译时会检测语法错误. 当检测到一个错误,解释器会引发一个异常 ...

  10. error 系统错误 错误码10007_Python学习之错误调试和测试

    Python学习之错误调试和测试 Python学习目录 在Mac下使用Python3 Python学习之数据类型 Python学习之函数 Python学习之高级特性 Python学习之函数式编程 Py ...

最新文章

  1. 后端开发之libcurl库编译与安装
  2. 微型计算机系统没有的总线是( ),微型计算机系统总线(1).ppt
  3. HTML5 WebSocket之HelloWorld
  4. java 获取当前时间月加1 ,年加1
  5. Cpp / shared_ptr 配置删除器的方法
  6. sybase性能优化经验浅谈
  7. 一站式金融云托管服务 都匀融通村镇银行系统成功上线运行
  8. ssl初一组周六模拟赛【2018.3.24】
  9. 数据结构算法 | 单调栈
  10. linux使用教程_iTOP-4412-QtE系统源码以及Linux系统-wfi设置以及使用文档 - 心底狂像...
  11. 安装PetShop后调试的诸多问题
  12. UE4开发游戏的流程
  13. flutter框架优缺点,flutter开发的app有哪些
  14. 开放世界游戏中的大地图的实现——程序技术篇
  15. 你想成为什么样的人取决于你付出了多少?
  16. 今日头条文章爬虫实战
  17. 计算机组成原理笔记(王道考研) 第六章:总线
  18. 苹果CMSV10本地DPLAYER播放器自动下一集设置教程
  19. 医疗——医院信息管理系统
  20. 工业机械设备设计与艺术设计

热门文章

  1. CentOS6.4 LVS+keepalived高可用负载均衡服务配置
  2. JavaScript 省市县数据
  3. GRE tunnel ×××
  4. poj 1511 Invitation Cards spfa 基础题!!虽然我做的比较坎坷!!可以练手啊!!
  5. 「Mac新手必备」解决 Mac 无法启动、开机的问题
  6. 剪切板记录管理工具:Paste Mac
  7. 蓝牙设备一键切换工具ToothFairy for Mac中文
  8. XnConvert for Mac(批量图像格式转换软件)
  9. macOS的Fn键实用技巧
  10. Docker 命令总结