Python 异常处理


Python 提供了两个非常重要的特性来处理 Python 程序中的任何意外错误并在其中添加调试功能:

  • 异常处理 : 这将在本教程中介绍。以下是 Python 中可用的标准异常列表: 标准例外 .

  • 断言 : 这将被覆盖 Python 中的断言 教程。

标准例外列表:

序号. 异常名称和描述
1

例外

所有异常的基类

2

停止迭代

当迭代器的 next() 方法不指向任何对象时引发。

3

系统退出

由 sys.exit() 函数引发。

4

标准错误

除 StopIteration 和 SystemExit 之外的所有内置异常的基类。

5

算术错误

数值计算发生的所有错误的基类。

6

溢出错误

当计算超出数值类型的最大限制时引发。

7

浮点错误

当浮点计算失败时引发。

8

零除法错误

当所有数字类型发生除零或模零时引发。

9

断言错误

在 Assert 语句失败的情况下引发。

10

属性错误

在属性引用或分配失败的情况下引发。

11

EOFError

当 raw_input() 或 input() 函数没有输入并且到达文件末尾时引发。

12

导入错误

当导入语句失败时引发。

13

键盘中断

当用户中断程序执行时引发,通常通过按 Ctrl+c。

14

查找错误

所有查找错误的基类。

15

索引错误

在序列中未找到索引时引发。

16

KeyError

当在字典中找不到指定的键时引发。

17

名称错误

在本地或全局命名空间中找不到标识符时引发。

18

UnboundLocalError

尝试访问函数或方法中的局部变量但未为其分配值时引发。

19

环境错误

在 Python 环境之外发生的所有异常的基类。

20

IOError

当输入/输出操作失败时引发,例如尝试打开不存在的文件时的 print 语句或 open() 函数。

21

IOError

针对与操作系统相关的错误引发。

22

语法错误

当 Python 语法出现错误时引发。

23

缩进错误

未正确指定缩进时引发。

24

系统错误

当解释器发现内部问题时引发,但遇到此错误时 Python 解释器不会退出。

25

系统退出

当使用 sys.exit() 函数退出 Python 解释器时引发。如果未在代码中处理,则导致解释器退出。

26

类型错误

当尝试对指定数据类型无效的操作或函数时引发。

27

值错误

当数据类型的内置函数具有有效的参数类型,但参数指定的值无效时引发。

28

运行时错误

当生成的错误不属于任何类别时引发。

29

未实现错误

当需要在继承的类中实现的抽象方法没有实际实现时引发。

Python 中的断言

断言是一种健全性检查,你可以在完成程序测试后打开或关闭它。

想一个断言最简单的方法就是把它比作一个 raise-if 声明(或者更准确地说,一个 raise-if-not 声明)。测试表达式,如果结果为假,则引发异常。

断言由 assert 语句执行,它是 Python 的最新关键字,在 1.5 版中引入。

程序员经常在函数开头放置断言以检查有效输入,并在函数调用之后检查有效输出。

The assert 陈述

当遇到断言语句时,Python 会计算伴随的表达式,希望这是真的。如果表达式为假,Python 会引发 断言错误 例外。

The syntax 对于断言是:

assert Expression[, Arguments]

如果断言失败,Python 使用 ArgumentExpression 作为 AssertionError 的参数。 AssertionError 异常可以像使用 try-except 语句的任何其他异常一样被捕获和处理,但如果不处理,它们将终止程序并产生回溯。

例子

这是一个将温度从开尔文度转换为华氏度的函数。由于零度开尔文温度非常低,如果它看到负温度,函数就会退出:

#!/usr/bin/python
def KelvinToFahrenheit(Temperature):
    assert (Temperature >= 0),"Colder than absolute zero!"
    return ((Temperature-273)*1.8)+32
print KelvinToFahrenheit(273)
print int(KelvinToFahrenheit(505.78))
print KelvinToFahrenheit(-5)

执行上述代码时,会产生如下结果:

32.0
451
Traceback (most recent call last):
File "test.py", line 9, in <module>
print KelvinToFahrenheit(-5)
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0),"Colder than absolute zero!"
AssertionError: Colder than absolute zero!

什么是异常?


异常是在程序执行期间发生的事件,它破坏了程序指令的正常流程。通常,当 Python 脚本遇到无法应对的情况时,它会引发异常。异常是表示错误的 Python 对象。

当 Python 脚本引发异常时,它必须立即处理异常,否则它会终止并退出。

处理异常


如果你有一些 可疑的 可能引发异常的代码,你可以通过将可疑代码放在 try: 堵塞。在 try: 块之后,包含一个 except: 语句,后跟一段代码,尽可能优雅地处理问题。

语法

这是简单的语法 尝试....除了...其他 blocks:

try:
    You do your operations here;
    ......................
except ExceptionI:
    If there is ExceptionI, then execute this block.
except ExceptionII:
    If there is ExceptionII, then execute this block.
    ......................
else:
    If there is no exception then execute this block.

以下是关于上述语法的几个要点:

  • 一个 try 语句可以有多个 except 语句。当 try 块包含可能引发不同类型异常的语句时,这很有用。

  • 你还可以提供一个通用的 except 子句,它处理任何异常。

  • 在 except 子句之后,你可以包含一个 else 子句。如果 try: 块中的代码没有引发异常,则执行 else 块中的代码。

  • else 块是不需要 try: 块保护的代码的好地方。

例子

这个例子打开一个文件,在文件中写入内容,然后优雅的出来,因为完全没有问题:

#!/usr/bin/python

try:
    fh = open("testfile", "w")
    fh.write("This is my test file for exception handling!!")
except IOError:
    print "Error: can\'t find file or read data"
else:
    print "Written content in the file successfully"
    fh.close()

这会产生以下结果:

Written content in the file successfully

例子

这个例子试图打开一个你没有写权限的文件,所以会抛出一个异常:

#!/usr/bin/python

try:
    fh = open("testfile", "r")
    fh.write("This is my test file for exception handling!!")
except IOError:
    print "Error: can\'t find file or read data"
else:
    print "Written content in the file successfully"

这会产生以下结果:

Error: can't find file or read data

The except 无例外条款


也可以使用不带异常的except语句,定义如下:

try:
    You do your operations here;
    ......................
except:
    If there is any exception, then execute this block.
    ......................
else:
    If there is no exception then execute this block.

这种一 尝试除外 语句捕获所有发生的异常。但是,使用这种 try-except 语句并不被认为是一种好的编程习惯,因为它会捕获所有异常,但不会使程序员确定可能发生的问题的根本原因。

The except 有多个例外的子句


你也可以使用相同的 except 处理多个异常的语句如下:

try:
    You do your operations here;
    ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
    If there is any exception from the given exception list,
    then execute this block.
    ......................
else:
    If there is no exception then execute this block.

try-finally 子句


你可以使用一个 finally: 与一个 try: 堵塞。 finally 块是放置任何必须执行的代码的地方,无论是 try 块 是否引发异常。 try-finally 语句的语法是这样的:

try:
    You do your operations here;
    ......................
    Due to any exception, this may be skipped.
finally:
    This would always be executed.
    ......................

你不能使用 else 子句以及 finally 子句。

例子

#!/usr/bin/python

try:
    fh = open("testfile", "w")
    fh.write("This is my test file for exception handling!!")
finally:
    print "Error: can\'t find file or read data"

如果你没有权限以写入模式打开文件,则会产生以下结果:

Error: can't find file or read data

同样的例子可以写得更干净,如下:

#!/usr/bin/python

try:
    fh = open("testfile", "w")
    try:
        fh.write("This is my test file for exception handling!!")
    finally:
        print "Going to close the file"
        fh.close()
except IOError:
    print "Error: can\'t find file or read data"

当在 try 块,执行立即传递给 finally 堵塞。在所有声明之后 finally 块被执行,异常再次引发并在 except 语句(如果存在于下一个更高层) 尝试除外 陈述。

异常论证


异常可以有 argument ,这是一个提供有关问题的附加信息的值。参数的内容因例外而异。你可以通过在 except 子句中提供一个变量来捕获异常的参数,如下所示:

try:
    You do your operations here;
    ......................
except ExceptionType, Argument:
    You can print value of Argument here...

如果你编写代码来处理单个异常,则可以在 except 语句中的异常名称后面添加一个变量。如果要捕获多个异常,则可以在异常的元组后面添加一个变量。

这个变量接收异常的值,主要包含异常的原因。变量可以接收单个值或元组形式的多个值。该元组通常包含错误字符串、错误编号和错误位置。

例子

以下是单个异常的示例:

#!/usr/bin/python

# Define a function here.
def temp_convert(var):
    try:
        return int(var)
    except ValueError, Argument:
        print "The argument does not contain numbers\n", Argument

# Call above function here.
temp_convert("xyz");

这会产生以下结果:

The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'

引发异常


你可以使用 raise 语句以多种方式引发异常。的一般语法 raise 声明如下。

语法

raise [Exception [, args [, traceback]]]

Here, 例外 是异常的类型(例如,NameError)和 argument 是异常参数的值。参数是可选的;如果未提供,则异常参数为无。

最后一个参数 traceback 也是可选的(在实践中很少使用),如果存在,它是用于异常的 traceback 对象。

例子

异常可以是字符串、类或对象。 Python 核心引发的大多数异常都是类,其参数是类的实例。定义新的异常非常容易,可以按如下方式完成:

def functionName( level ):
    if level < 1:
        raise "Invalid level!", level
        # The code below to this would not be executed
        # if we raise the exception

注意: 为了捕获异常,“except”子句必须引用类对象或简单字符串引发的相同异常。例如,要捕获上述异常,我们必须编写 except 子句,如下所示:

try:
    Business Logic here...
except "Invalid level!":
    Exception handling here...
else:
    Rest of the code here...

用户定义的异常


Python 还允许你通过从标准内置异常派生类来创建自己的异常。

这是一个与 运行时错误 .在这里,创建了一个从以下子类化的类 运行时错误 .当你需要在捕获异常时显示更具体的信息时,这很有用。

在 try 块中,引发用户定义的异常并在 except 块中捕获。变量 e 用于创建类的实例 网络错误 .

class Networkerror(RuntimeError):
    def __init__(self, arg):
        self.args = arg

所以一旦你定义了上面的类,你可以引发如下异常:

try:
    raise Networkerror("Bad hostname")
except Networkerror,e:
    print e.args