Python异常处理机制结构实例解析

首先,Python 完整的异常处理语法结构如下:

try:
  #业务实现代码
except Exception1 as e:
  #异常处理块1
  ...
except Exception2 as e:
  #异常处理块2
  ...
#可以有多个 except
...
else:
  #正常处理块
finally :
  #资源回收块
  ...

整个异常处理结构的执行过程,如图 1 所示。

注意,在整个异常处理结构中,只有 try 块是必需的,也就是说:

  • 如果没有 try 块,则不能有后面的 except 块、else 块和 finally 块。但是也不能只使用 try 块,要么使用 try except 结构,要么使用 try finally 结构;
  • except 块、else 块、finally 块都是可选的,当然也可以同时出现;
  • 可以有多个 except 块,但捕获父类异常的 except 块应该位于捕获子类异常的 except 块的后面;
  • 多个 except 块必须位于 try 块之后,finally 块必须位于所有的 except 块之后。
  • 要使用 else 块,其前面必须包含 try 和 except。

其中,很多初学者分不清 finally 和 else 的区别,这里着重说一下。else 语句块只有在没有异常发生的情况下才会执行,而 finally 语句则不管异常是否发生都会执行。不仅如此,无论是正常退出、遇到异常退出,还是通过 break、continue、return 语句退出,finally 语句块都会执行。

注意,如果程序中运行了强制退出 Python 解释器的语句(如 os._exit(1) ),则 finally 语句将无法得到执行。例如:

import os
try:
  os._exit(1)
finally:
  print("执行finally语句")

运行程序,没有任何输出。因此,除非在 try 块、except 块中调用了退出 Python 解释器的方法,否则不管在 try 块、except 块中执行怎样的代码,出现怎样的情况,异常处理的 finally 块总会被执行。

另外在通常情况下,不要在 finally 块中使用如 return 或 raise 等导致方法中止的语句(raise 语句将在后面介绍),一旦在 finally 块中使用了 return 或 raise 语句,将会导致 try 块、except 块中的 return、raise 语句失效。看如下程序:

def test():
  try:
    # 因为finally块中包含了return语句
    # 所以下面的return语句失去作用
    return True
  finally:
    return False
print(test())

上面程序在 finally 块中定义了一条 return False 语句,这将导致 try 块中的 return true 失去作用。运行上面程序,输出结果为:

False

同样,如果 Python 程序在执行 try 块、except 块包含有 return 或 raise 语句,则 Python 解释器执行到该语句时,会先去查找 finally 块,如果没有 finally 块,程序才会立即执行 return 或 raise 语句;反之,如果找到 finally 块,系统立即开始执行 finally 块,只有当 finally 块执行完成后,系统才会再次跳回来执行 try 块、except 块里的 return 或 raise 语句。

但是,如果在 finally 块里也使用了 return 或 raise 等导致方法中止的语句,finally 块己经中止了方法,系统将不会跳回去执行 try 块、except 块里的任何代码。

尽量避免在 finally 块里使用 return 或 raise 等导致方法中止的语句,否则可能出现一些很奇怪的情况。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2020-07-23

Python使用sys.exc_info()方法获取异常信息

在实际调试程序的过程中,有时只获得异常的类型是远远不够的,还需要借助更详细的异常信息才能解决问题. 捕获异常时,有 2 种方式可获得更多的异常信息,分别是: 使用 sys 模块中的 exc_info 方法: 使用 traceback 模块中的相关函数. 本节首先介绍如何使用 sys 模块中的 exc_info() 方法获得更多的异常信息. 有关 sys 模块更详细的介绍,可阅读<Python sys模块>. 模块 sys 中,有两个方法可以返回异常的全部信息,分别是 exc_info() 和

解决python ThreadPoolExecutor 线程池中的异常捕获问题

问题 最近写了涉及线程池及线程的 python 脚本,运行过程中发现一个有趣的现象,线程池中的工作线程出现问题,引发了异常,但是主线程没有捕获异常,还在发现 BUG 之前一度以为线程池代码正常返回. 先说重点 这里主要想介绍 python concurrent.futuresthread.ThreadPoolExecutor 线程池中的 worker 引发异常的时候,并不会直接向上抛起异常,而是需要主线程通过调用concurrent.futures.Future.exception(timeou

解决Python 异常TypeError: cannot concatenate &#39;str&#39; and &#39;int&#39; objects

TypeError: cannot concatenate 'str' and 'int' objects print str + int 的时候就会这样了 python + 作为连接符的时候,不会自动给你把int转换成str 补充知识:TypeError: cannot concatenate 'str' and 'list' objects和Python读取和保存图片 运行程序时报错,然后我将list转化为str就好了. 利用''.join(list) 如果需要用逗号隔开,如1,2,3,4则

使用Python将Exception异常错误堆栈信息写入日志文件

假设需要把发生异常错误的信息写入到log.txt日志文件中去: import traceback import logging logging.basicConfig(filename='log.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') try: raise Exception('发生异常错误信息') except: #方案一,自己定义一个文件,自己把错误堆栈信息写入文件. #er

python except异常处理之后不退出,解决异常继续执行的实现

写了个等待分析结果,解析分析结果json的脚本 那个文件生成时候有点大,有时候监测到新文件就去解析可能文件只生成了一半,就会抛出异常退出当前线程,此次的分析结果就丢失了,如果load json文件失败,一般就是上百M到几G的json大文件,等待10秒,如果再次load失败,重新再load一次,这样脚本看上去挺繁琐的,监控线程又只能监控文件的创建,修改和删除,不知道创建的文件是否写完毕. def run_analyze(): sleep(2) berror = True temp = {} whi

python3 使用traceback定位异常实例

1.我们使用正常的输出语句 得到的是(输出结果:division by zero)虽然得到了错误的日志输出,但是不知道为什么出错,也不能定位具体出错位置. 2.现在我们使用 traceback 就可以得到具体的错误,以及定位到出错的位置.这样就能更方便调试错误. 参考文献 traceback文档地址: https://docs.python.org/2/library/traceback.html 以下为google翻译(仅供参考,): 该模块提供了一个标准接口,用于提取,格式化和打印Pytho

Python random库使用方法及异常处理方案

1.random库的使用: random库是使用随机数的Python标准库 从概率论角度来说,随机数是随机产生的数据(比如抛硬币),但时计算机是不可能产生随机值,真正的随机数也是在特定条件下产生的确定值,只不过这些条件我们没有理解,或者超出了我们的理解范围.计算机不能产生真正的随机数,那么伪随机数也就被称为随机数 --伪随机数:计算机中通过采用梅森旋转算法生成的(伪)随机序列元素 python中用于生成伪随机数的函数库是random 因为是标准库,使用时候只需要importrandom rand

Python基于traceback模块获取异常信息

除了使用 sys.exc_info() 方法获取更多的异常信息之外,还可以使用 traceback 模块,该模块可以用来查看异常的传播轨迹,追踪异常触发的源头. 下面示例显示了如何显示异常传播轨迹: class SelfException(Exception): pass def main(): firstMethod() def firstMethod(): secondMethod() def secondMethod(): thirdMethod() def thirdMethod():

python使用wmi模块获取windows下硬盘信息的方法

本文实例讲述了python使用wmi模块获取windows下硬盘信息的方法.分享给大家供大家参考.具体实现方法如下: # -*- coding: utf-8 -*- #import ######################################################################## import os, sys import time import wmi ################################################

Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例

本文实例讲述了Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能.分享给大家供大家参考,具体如下: 因为需要使用叶子节点的路径来作为特征,但是原始的lxml模块解析之后得到的却是整个页面中所有节点的xpath路径,不是我们真正想要的形式,所以就要进行相关的处理才行了,差了很多网上的博客和文档也没有找到一个是关于输出html中全部叶子节点的API接口或者函数,也可能是自己没有那份耐心,没有找到合适的资源,只好放弃了寻找,但是这并不说明没有其他的方法了,在对页面全部节点

Python基于FTP模块实现ftp文件上传操作示例

本文实例讲述了Python基于FTP模块实现ftp文件上传操作.分享给大家供大家参考,具体如下: #!/usr/bin/python #-*- coding:utf-8 -*- from ftplib import FTP #加载ftp模块 ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect("IP","port") #连接的ftp sever和端口 ftp.login("us

python使用wmi模块获取windows下的系统信息 监控系统

Python用WMI模块获取Windows系统的硬件信息:硬盘分区.使用情况,内存大小,CPU型号,当前运行的进程,自启动程序及位置,系统的版本等信息. 本文实例讲述了python使用wmi模块获取windows下的系统信息 监控系统 #!/usr/bin/env python # -*- coding: utf- -*- #http://www.cnblogs.com/liu-ke/ import wmi import os import sys import platform import

Python基于Pymssql模块实现连接SQL Server数据库的方法详解

本文实例讲述了Python基于Pymssql模块实现连接SQL Server数据库的方法.分享给大家供大家参考,具体如下: 数据库版本:SQL Server 2012. 按照Python版本来选择下载pymssql模块,这样才能连接上sql server. 我安装的python版本是3.5 ,64位的,所以下载的pymssql模块是:pymssql-2.1.3-cp35-cp35m-win_amd64.whl 我把文件下载后放到E盘,安装pymssql模块: C:\Users\Administr

Python基于csv模块实现读取与写入csv数据的方法

本文实例讲述了Python基于csv模块实现读取与写入csv数据的方法.分享给大家供大家参考,具体如下: 通过csv模块可以轻松读取格式为csv的文件,而且csv模块是python内置的,不需要下载就可以直接用. 一.准备csv文件 文件名是 e:\t.csv,文件内容: org_id,org_name,state,emp_id 1,销售1,'1',123 2,销售2,'0',321 3,销售3,'1',231 1,,'1',1234 二.读取csv数据 代码非常简单: # -*- coding

Python基于whois模块简单识别网站域名及所有者的方法

本文实例讲述了Python基于whois模块简单识别网站域名及所有者的方法.分享给大家供大家参考,具体如下: 对于一些网站,我们可能会关心其所有者是谁.为了找到网站的所有者,我们可以使用WHOIS协议查询域名的注册者是谁.Python中有一个对该协议的封装库.我们可以通过pip进行安装. pip install python-whois 补充:本机安装了Python2与Python3两个版本,这里就使用了pip2安装python-whois模块,如下图所示: 本机Python3环境下适用pip3

Python基于Tkinter模块实现的弹球小游戏

本文实例讲述了Python基于Tkinter模块实现的弹球小游戏.分享给大家供大家参考,具体如下: #!usr/bin/python #-*- coding:utf-8 -*- from Tkinter import * import Tkinter import random import time #创建小球的类 class Ball: def __init__(self,canvas,paddle,color): #参数:画布,球拍和颜色 self.canvas = canvas self

Python基于xlrd模块操作Excel的方法示例

本文实例讲述了Python基于xlrd模块操作Excel的方法.分享给大家供大家参考,具体如下: 一.使用xlrd读取excel 1.xlrd的安装: pip install xlrd==0.9.4 2.基本操作示例: #coding: utf-8 import xlrd #导入xlrd模块 xlsfile=r"D:\workspace\host.xls" #获得excel的book对象 book = xlrd.open_workbook(filename=None, file_con

Python基于time模块求程序运行时间的方法

本文实例讲述了Python基于time模块求程序运行时间的方法.分享给大家供大家参考,具体如下: 要记录程序的运行时间可以利用Unix系统中,1970.1.1到现在的时间的毫秒数,这个时间戳轻松完成. 方法是程序开始的时候取一次存入一个变量,在程序结束之后取一次再存入一个变量,与程序开始的时间戳相减则可以求出. Python中取这个时间戳的方法为引入time类之后,使用time.time();就能够拿出来.也就是Java中的System.currentTimeMillis(). 由于Python