Python中的异常(Exception)处理
异常
当你的程序出现例外情况时就会发生异常(Exception)。例如,当你想要读取一个文件时,而那个文件却不存在,怎么办?又或者你在程序执行时不小心把它删除了,怎么办?这些通过使用异常来进行处理。
类似地,如果你的程序中出现了一些无效的语句该怎么办?Python 将会对此进行处理,举起(Raises)它的小手来告诉你哪里出现了一个错误(Error)。
错误
你可以想象一个简单的 print 函数调用。如果我们把 print 误拼成 Print 会怎样?你会注意到它的首字母是大写。在这一例子中,Python 会抛出(Raise)一个语法错误。
>>> Print("Hello World")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Print' is not defined >>> print("Hello World")
Hello World
你会注意到一个 NameError 错误被抛出,同时 Python 还会打印出检测到的错误发生的位置。这就是一个错误错误处理器(Error Handler)2 为这个错误所做的事情。
异常
我们将尝试(Try)去读取用户的输入内容。按下 [ctrl-d] 来看看会发生什么事情。
>>> s = input('Enter something --> ')
Enter something --> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
EOFError
此处 Python 指出了一个称作 EOFError 的错误,代表着它发现了一个文件结尾(End of File)符号(由 ctrl-d 实现)在不该出现的时候出现了。
处理异常
我们可以通过使用 try..except 来处理异常状况。一般来说我们会把通常的语句放在 try 代码块中,将我们的错误处理器代码放置在 except 代码块中。
案例(保存文 exceptions_handle.py):
try:
text = input('Enter something --> ') except EOFError:
print('Why did you do an EOF on me?') except KeyboardInterrupt:
print('You cancelled the operation.') else:
print('You entered {}'.format(text))
输出:
# Press ctrl + d
$ python exceptions_handle.py
Enter something --> Why did you do an EOF on me? # Press ctrl + c
$ python exceptions_handle.py
Enter something --> ^CYou cancelled the operation. $ python exceptions_handle.py
Enter something --> No exceptions
You entered No exceptions
它是如何工作的
我们将所有可能引发异常或错误的语句放在 try 代码块中,并将相应的错误或异常的处理器(Handler)放在 except 子句或代码块中。except 子句可以处理某种特定的错误或异常,或者是一个在括号中列出的错误或异常。如果没有提供错误或异常的名称,它将处理所有错误与异常。
要注意到必须至少有一句 except 字句与每一句 try 字句相关联。不然,有一个 try 代码块又有什么意义?
如果没有任何错误或异常被处理,那么将调用 Python 默认处理器,它只会终端程序执行并打印出错误信息。我们已经在前面的章节里见过了这种处理方式。
你还可以拥有一个 else 子句与 try..except 代码块相关联。else 子句将在没有发生异常的时候执行。
在下一个案例中,我们还将了解如何获取异常对象以便我们可以检索其他信息。
抛出异常3
你可以通过 raise 语句来引发一次异常,具体方法是提供错误名或异常名以及要抛出(Thrown)异常的对象。
你能够引发的错误或异常必须是直接或间接从属于 Exception(异常) 类的python 派生类。
案例(保存为 exceptions_raise.py):
# encoding=UTF-8 class ShortInputException(Exception): '''一个由用户定义的异常类''' def __init__(self, length, atleast): Exception.__init__(self)
self.length = length
self.atleast = atleast try:
text = input('Enter something --> ') if len(text) < 3: raise ShortInputException(len(text), 3) # 其他工作能在此处继续正常运行 except EOFError:
print('Why did you do an EOF on me?') except ShortInputException as ex:
print(('ShortInputException: The input was ' + '{0} long, expected at least {1}')
.format(ex.length, ex.atleast)) else:
print('No exception was raised.')
输出:
$ python exceptions_raise.py
Enter something --> a
ShortInputException: The input was 1 long, expected at least 3 $ python exceptions_raise.py
Enter something --> abc
No exception was raised.
它是如何工作的
在本例中,我们创建了我们自己的异常类型。这一新的异常类型叫作 ShortInputException。它包含两个字段——获取给定输入文本长度的 length,程序期望的最小长度 atleast。
在 except 子句中,我们提及了错误类,将该类存储 as(为) 相应的错误名或异常名。这类似于函数调用中的形参与实参。在这个特殊的 except 子句中我们使用异常对象的 length 与 atleast 字段来向用户打印一条合适的信息。
Try ... Finally
假设你正在你的读取中读取一份文件。你应该如何确保文件对象被正确关闭,无论是否会发生异常?这可以通过 finally 块来完成。
保存该程序为 exceptions_finally.py:
import sys import time f = None try:
f = open("poem.txt") # 我们常用的文件阅读风格 while True:
line = f.readline() if len(line) == 0: break print(line, end='')
sys.stdout.flush()
print("Press ctrl+c now") # 为了确保它能运行一段时间 time.sleep(2) except IOError:
print("Could not find file poem.txt") except KeyboardInterrupt:
print("!! You cancelled the reading from the file.") finally: if f:
f.close()
print("(Cleaning up: Closed the file)")
输出:
$ python exceptions_finally.py
Programming is fun
Press ctrl+c now
^C!! You cancelled the reading from the file.
(Cleaning up: Closed the file)
它是如何工作的
我们按照通常文件读取进行操作,但是我们同时通过使用 time.sleep 函数任意在每打印一行后插入两秒休眠,使得程序运行变得缓慢(在通常情况下 Python 运行得非常快速)。当程序在处在运行过过程中时,按下 ctrl + c 来中断或取消程序。
你会注意到 KeyboardInterrupt 异常被抛出,尔后程序退出。不过,在程序退出之前,finally 子句得到执行,文件对象总会被关闭。
另外要注意到我们在 print 之后使用了 sys.stout.flush(),以便它能被立即打印到屏幕上。
with 语句
在 try 块中获取资源,然后在 finally 块中释放资源是一种常见的模式。因此,还有一个 with 语句使得这一过程可以以一种干净的姿态得以完成。
保存为 exceptions_using_with.py:
with open("poem.txt") as f: for line in f:
print(line, end='')
它是如何工作的
程序输出的内容应与上一个案例所呈现的相同。本例的不同之处在于我们使用的是 open 函数与 with 语句——我们将关闭文件的操作交由 with open 来自动完成。
在幕后发生的事情是有一项 with 语句所使用的协议(Protocol)。它会获取由 open 语句返回的对象,在本案例中就是“thefile”。
它总会在代码块开始之前调用 thefile.__enter__ 函数,并且总会在代码块执行完毕之后调用 thefile.__exit__。
因此,我们在 finally 代码块中编写的代码应该格外留心 __exit__ 方法的自动操作。这能够帮助我们避免重复显式使用 try..finally 语句。
有关Python教程中这话题的更多讨论已经超出了本书所能涉及的范围,因此请参考 PEP 343 来了解更加全面的解释。
总结
我们已经讨论了 try..except 和 try..finally 语句的用法。同时我们也已经看到了如何创建我们自己的python 异常类型,还有如何抛出异常。
接下来,我们将探索 Python 的标准库。
Python中的异常(Exception)处理的更多相关文章
- Python中获取异常(Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置.下面介绍几种python中获取异常信息的方法,这里获取异常(Exception)信息采用try...except...程序 ...
- Python中获取异常(try Exception)信息
异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置. 这里获取异常(Exception)信息采用try...except...程序结构.如下所示: try: ... exce ...
- 【Python】解析Python中的异常操作
目录结构: contents structure [-] try,except,else,finally块 异常处理 使用except而不带任何异常类型 使用except而带多种异常类型 try-fi ...
- Python基础之:Python中的异常和错误
目录 简介 Python中的内置异常类 语法错误 异常 异常处理 抛出异常 异常链 自定义异常 finally 简介 和其他的语言一样,Python中也有异常和错误.在 Python 中,所有异常都是 ...
- python中的异常如何处理
一.异常基础 在编程程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面. try: #正常逻辑代码 input = raw_input("输入数字:") data ...
- python中的异常
Python提供了两个非常重要的功能来处理异常和错误: 1) 异常处理try-.except 2) 断言assert 异常和断言,可以用于我们调试python程序,跟踪程序执行状态,尽快排查问题. 3 ...
- 一文教你读懂Python中的异常信息
正文共:11813 字 2 图 预计阅读时间: 30 分钟 原文:https://realpython.com/python-traceback/ 译者:陈祥安 原文有所改动. 在写 Python 代 ...
- java中的异常(Exception)
基本概念 将程序执行中发生的不正常的情况称为"异常".开发中的语法错误和逻辑错误不是异常 执行过程中的异常事件可分为两大类 错误(Error):Java虚拟机无法解决的严重问题.例 ...
- 『无为则无心』Python函数 — 38、Python中的异常
目录 1.异常概念 2.了解异常 3.异常的写法 (1)语法 (2)快速体验 (3)捕获指定异常 (4)异常中的else (5)异常中的finally (6)总结 1.异常概念 定义:程序在运行过程当 ...
随机推荐
- 转载】JQuery中如何传递参数如click(),change()等具体实现
转载地址:http://www.jb51.net/article/36249.htm 有个需求让两个select中option相互转换,这个作业就是给几个按钮添加click()事件接下来为大家介绍下如 ...
- bzoj1808 [Ioi2007]training 训练路径
Description 马克(Mirko)和斯拉夫克(Slavko)正在为克罗地亚举办的每年一次的双人骑车马拉松赛而紧张训练.他们需要选择一条训练路径. 他们国家有N个城市和M条道路.每条道路连接两个 ...
- python第十四课--排序及自定义函数之案例二:冒泡排序
案例二:冒泡排序 lt1=[45,12,56,-32,-3,44,75,-22,100] print('排序前:'+str(lt1)) 自定义函数:实现冒泡排序(升序)原则:1).有没有形参?有,接受 ...
- [HNOI2002]营业额统计(splay基础)
嘟嘟嘟 这几天开始搞平衡树了,\(splay\)理解起来感觉还行,然而代码看了半天才勉强看懂. 我这篇博客应该不算什么入门讲解,因为我觉得我讲不明白,所以只能算自己的学习笔记吧. 这道题就是有\(n\ ...
- Hive学习之路 (六)Hive SQL之数据类型和存储格式
一.数据类型 1.基本数据类型 Hive 支持关系型数据中大多数基本数据类型 类型 描述 示例 boolean true/false TRUE tinyint 1字节的有符号整数 -128~127 1 ...
- C# 生成自签名CA证书
"; string signatureAlgorithm = "SHA1WithRSA"; // Generate RSA key pair var rsaGenerat ...
- virtualbox+vagrant学习-3-Vagrant Share-3-SSH Sharing
SSH Sharing vagrant share通过向vagrant share提供--SSH标志,使远程SSH访问vagrant环境变得非常容易. 如果你想让同事访问你的SSH,以便对ops问题进 ...
- 图片保持比例,padding的妙用
要保持图片的比例不变 这一张图片在不同分辨率(1980px, 1364px,移动端400px)下均保持了一定的比例不变. 方法: padding以及margin的上下(margin-top | mar ...
- 集合之Iterator
迭代对于我们搞Java的来说绝对不陌生.我们常常使用JDK提供的迭代接口进行Java集合的迭代. Iterator iterator = list.iterator(); while(iterator ...
- datagrid 完整dom结构
<!-- datagrid的最外层容器,可以使用$(target).datagrid('getPanel')或者$.data(target,'datagrid').panel得到这个DOM对象, ...