简介

当程序发生意外情况时则产生异常。

例如你需要读一个文件而这个文件并不存在会咋样?又或者是程序运行时你把它误删除了呢?

上述情形通过异常进行处理。

类似的,如果你的程序存在一些非法语句会发生什么呢?这时python会举手告诉你存在一个错误。

错误

考虑一个简单的print函数调用。如果我们把print错拼成Print(注意大小写),这时python将引发一个语法错误。

>>> Print('Hello World')

Traceback (most recent call last):

File "<pyshell#0>", line 1, in <module>

Print('Hello World')

NameError: name 'Print' is not defined

>>> print('Hello World')

Hello World

我们看到一个NameError被引发并且发生错误的位置也被打印出来。这就是一个错误处理器(error handler)为这个错误所进行的处理。

异常

我们尝试从用户读取输入,看看当键入ctrl-d(注:windows用户输入ctrl-z)时会发生什么。

>>> s = input('Enter something --> ')

Enter something -->

Traceback (most recent call last):

File "<pyshell#2>", line 1, in <module>

s = input('Enter something --> ')

EOFError: EOF when reading a line

(注:也许你看到的信息会所有不同,但只要引发了EOFError即可)

可以看到python引发了一个被称作EOFError的异常,一般这意味着它遇到了一个非期望的文件尾(end of file)符号(注:windows下为ctrl-z)

处理异常

利用try...except语句使得我们可以处理异常。通常我们将语句放入try块而将错误处理放到except块中。

#!/usr/bin/python

# Filename: try_except.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 {0}'.format(text))

输出:

$ python try_except.py

Enter something -->     # Press ctrl-d

Why did you do an EOF on me?

$ python try_except.py

Enter something -->     # Press ctrl-c

You cancelled the operation.

$ python try_except.py

Enter something --> no exceptions

You entered no exceptions

代码如何工作:
我们将可能引起异常/错误的所有语句放入try块,然后将适当的错误/异常处理器放进except块/从句中。

except从句可以处理一个单一的指定的错误或异常,或者一组括在小括号中的异常/错误。

如果没有给出异常或错误,则except会处理所有的错误和异常。

注意每个try至少要关联一个except从句,否则只存在try块有啥意义呢?

任何没有被处理的错误或异常都会导致python默认处理器的调用,它的作用仅仅是终止程序运行并将错误信息打印出来。前面我们已经见识过了。

你还可以为try..except块关联一个else从句。如果没有异常发生则else块被执行。

下面的例子中,我们将看到如何得到异常对象获取额外的异常信息。

引发异常

通过raise语句你可以引发异常。为raise语句提供错误/异常名后异常对象会被抛出。

你抛出的错误或异常必须是一个间接或直接派生自Exception类的类。

#!/usr/bin/python

# Filename: raising.py

class ShortInputException(Exception):

'''A user-defined exception class.'''

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)

# Other work can continue as usual here

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 raising.py

Enter something --> a

ShortInputException: The input was 1 long, expected at least 3

$ python raising.py

Enter something --> abc

No exception was raised.

范例如何工作:

这里,我们创建了自己的异常类型。这个新的异常类型被称作ShortInputException

ShortInputException拥有两个字段 – length指出给定输入的长度,而atleast为程序希望输入的最小长度。

在except从句中,我们给定异常类并将其对象存储为一个变量。这就类似于函数调用中的形参与实参。

在这个特定的except从句中,我们利用异常对象的length和atleast字段向用户打印出适当的提示信息。

try...finally

假设你的程序正在读取一个文件。如何保证无论是否发生异常文件对象都能被适当的关闭?这可以通过finally块做到。

注意你可以同时为try块关联except和finally块。如果你希望同时使用两者则必须将一个嵌入另一个中。

#!/usr/bin/python

# Filename: finally.py

import time

try:

f = open('poem.txt')

while True: # our usual file-reading idiom

line = f.readline()

if len(line) == 0:

break

print(line, end='')

time.sleep(2) # To make sure it runs for a while

except KeyboardInterrupt:

print('!! You cancelled the reading from the file.')

finally:

f.close()

print('(Cleaning up: Closed the file)')

输出:

$ python finally.py

Programming is fun

When the work is done

if you wanna make your work also fun:

!! You cancelled the reading from the file.

(Cleaning up: Closed the file)

代码如何工作:

我们执行一个常见的读文件操作,但故意在打印每行后利用time.sleep函数让程序休眠2秒,因此程序会运行的比较慢。

当程序运行时输入ctrl-c将中断/取消程序的运行。

注意ctrl-c会导致抛出KeyboardInterrupt异常,随后程序结束。但在程序结束前finally会被执行因此文件对象永远都会被关闭。

with语句

在try块中获得资源后在finally块中释放之是很常见的设计方式。因此python提供with语句给予更简洁的实现方式。

#!/usr/bin/python

# Filename: using_with.py

with open("poem.txt") as f:

for line in f:

print(line, end='')

代码如何工作:

程序的输出应该和上面的范例相同。程序的不同之处在于我们在with语句中使用open函数 – 如此with语句就会自动关闭文件了。

在幕后with与用户有一个协议。它将读取open语句返回的对象,这里我们将这个对象称为”thefile”

在with块的开始处,with永远都会调用thefile.__enter__方法而在块结束处又会调用thefile.__exit__方法。

因此我们在finally块中的代码被委托给__exit__方法了。这将帮助我们避免反复的使用try..finally块。

关于此主题更多的讨论已经超出本书范围,详见(http://www.python.org/dev/peps/pep-0343/) (注:看本地文档也行)

小结

我们已经讨论了try...except和try...finally的用法。并了解到如何创建自己的异常类型与引发异常。

下面,我们将研究python标准库。

简明Python3教程 15.异常的更多相关文章

  1. 简明Python3教程(A Byte of Python 3)

    关键字:[A Byte of Python v1.92(for Python 3.0)] [A Byte of Python3] 简明Python教程 Python教程 简明Python3教程  简明 ...

  2. 简明python教程九----异常

    使用try...except语句来处理异常.我们把通常的语句放在try-块中,而把错误处理语句放在except-块中. import sys try: s = raw_input('Enter som ...

  3. 简明Python3教程 18.下一步是什么

    如果你有认真通读本书之前的内容并且实践其中包含的大量例程,那么你现在一定可以熟练使用python了. 同时你可能也编写了一些程序用于验证python特性并提高你的python技能.如果还没有这样做的话 ...

  4. 简明Python3教程 16.标准库

    简介 python标准库作为python标准安装的一部分,其自身包含数量庞大的实用模块, 因此熟悉python标准库非常重要,因为很多问题都能利用python标准库快速解决. 下面我们将研究标准库中的 ...

  5. 简明Python3教程 9.函数

    简介 函数是程序的可复用片段,允许你为语句块赋予名字之后在程序的任何地方运行它们任意次,这称做函数调用. 我们已经使用过一些内建函数,例如len和range等. 函数也许是任何有意义的软件中最重要的构 ...

  6. 简明Python3教程 7.运算符和表达式

    简介 你写的大多数逻辑行都包含表达式.表达式的一个简单例子是2 + 3.一个表达式可分为操作符和操作数两部分. 操作符的功能是执行一项任务:操作符可由一个符号或关键字代表,如+ .操作符需要数据以供执 ...

  7. 简明Python3教程 6.基础

    你肯定不满足于只打印"Hello World"吧? 你想要的更多 - 你希望得到一些输入,操纵它后再从中得到某些东西.我们可以使用python中的常量和变量实现这些功能. 字面常量 ...

  8. 简明Python3教程 5.第一步

    介绍 我们现在来看看如何在Python中运行传统的”Hello world”程序.这会教你如何写.保存以及运行Python程序. 有两种办法来运行您的Python程序——使用交互式的解释器提示符或者源 ...

  9. 简明Python3教程 4.安装

    如果你已经安装了Python 2.x,你不需要在安装Python 3.0前卸载Python 2.x.这两者可以共存. GNU/Linux用户和BSD用户 如果你使用类似于Ubuntu.Fedora.O ...

随机推荐

  1. [React Native] Disable and Ignore Yellow Box Warnings in React Native

    Yellow box warnings in react native can be intrusive. We will use console.disableYellowBox to disabl ...

  2. Hadoop集群日常运维 分类: A1_HADOOP 2015-03-01 21:26 502人阅读 评论(0) 收藏

    (一)备份namenode的元数据 namenode中的元数据非常重要,如丢失或者损坏,则整个系统无法使用.因此应该经常对元数据进行备份,最好是异地备份. 1.将元数据复制到远程站点 (1)以下代码将 ...

  3. [转载]MVC中单用户登录

    转自:http://www.cnblogs.com/firstcsharp/archive/2013/05/19/3087481.html 把下面这段代码放在登录用户验证以后:   //用户登录验证通 ...

  4. 【Heritrix基础教程之2】Heritrix基本内容介绍 分类: B1_JAVA H3_NUTCH 2014-06-01 13:02 878人阅读 评论(0) 收藏

    1.版本说明 (1)最新版本:3.3.0 (2)最新release版本:3.2.0 (3)重要历史版本:1.14.4 3.1.0及之前的版本:http://sourceforge.net/projec ...

  5. js循环json数组

    例如数据库里面的json字符串是这样的 var str = '[{"name":"宗2瓜","num":"1",&quo ...

  6. 为什么说 C/C++ 不适合做 Web 开发?(成本高,容易出错,apache等工具分担了大部分工作)

    因为大家在讨论用C#.Java,做出来的项目的时候,用C++的人们还在讨论语言特性 每种语言都有特定适用范围,对应着某类问题.web开发的重头戏不是计算,而是与用户交互和发送sql语句,当然以脚本语言 ...

  7. Android 自定义View——自定义点击事件

    每个人手机上都有通讯录,这是毫无疑问的,我们通讯录上有一个控件,在通讯录的最左边有一列从”#”到”Z”的字母,我们通过滑动或点击指定的字母来确定联系人的位置,进而找到联系人.我们这一节就通过开发这个控 ...

  8. jQuery Mobile手机网站案例

    jQuery Mobile手机网站案例 一.总结 一句话总结:jQuery Mobile是纯手机框架,和amazeui和bootstrap都可以做手机网站. 1.另一款文本编辑器? jd编辑器 二.j ...

  9. js进阶 10-1 JQuery是什么

    js进阶 10-1 JQuery是什么 一.总结 一句话总结: 1.两种引用jquery的方法? 可以在线jquery和本地jquery两种 2.jquery主要好处? 浏览器兼容问题 二.js进阶 ...

  10. Python 库的使用 —— dis

    dis:Disassembler of Python byte code into mnemonics. Java.Python.Ruby 1.9 这些语言均使用了栈机器型的 VM.因为是基于栈的实现 ...