热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

简明Python3教程15.异常

简介

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

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

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

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

 

错误

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

    >>> Print('Hello World')

    Traceback (most recent call last):

      File "", line 1, in

        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 "", line 1, in

        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标准库。

 

 

 

--------------Python书籍推荐-----------------
Python基础教程-第2版.修订版 
简明Python3教程 15.异常
购买地址1  购买地址2
 
 
PYTHON核心编程
简明Python3教程 15.异常
购买地址1  购买地址2
 
 
零基础学Python
简明Python3教程 15.异常
购买地址1  购买地址2

推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
author-avatar
风行汽车-赣州景通4S店
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有