Python3异常处理


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

  • 异常处理 :本教程将对此进行介绍。这是Python中可用的标准异常列表: 标准例外 .

  • 断言 :这将在 Python 3中的断言 教程。

标准例外


这是Python中可用的标准异常的列表:

序号 异常名称和描述
1

例外

所有异常的基类

2

StopIteration

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

3

系统退出

由sys.exit()函数引发。

4

标准错误

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

5

ArithmeticError

用于数值计算的所有错误的基类。

6

OverflowError

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

7

FloatingPointError

在浮点计算失败时引发。

8

ZeroDivisonError

当所有数值类型均被零除或取零时引发。

9

断言错误

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

10

AttributeError

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

11

EOFError

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

12

ImportError

在导入语句失败时引发。

13

键盘中断

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

14

LookupError

所有查找错误的基类。

15

IndexError

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

16

KeyError

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

17

NameError

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

18

UnboundLocalError

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

19

环境错误

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

20

IOError

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

21

OSError

因与操作系统相关的错误而引发。

22

语法错误

在Python语法错误时引发。

23

IndentationError

未正确指定缩进时引发。

24

系统错误

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

25

系统退出

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

26

TypeError

在尝试执行对指定数据类型无效的操作或功能时引发。

27

ValueError

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

28

RuntimeError

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

29

NotImplementedError

在未真正实现需要在继承的类中实现的抽象方法时引发。

Python断言


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

  • 想到一个断言的最简单方法是将其比喻为一个断言。 raise-if 声明(或更准确地说,是“如果不是,则引发”声明)。测试表达式,如果结果为假,则引发异常。

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

  • 程序员通常将断言放在函数的开头以检查有效输入,而在函数调用之后则进行断言以检查有效输出。

断言

当遇到断言语句时,Python会评估附带的表达式,希望它是正确的。如果表达式为假,Python会引发一个 断言错误 例外。

assert的语法为:

assert Expression[, Arguments]

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

这是将给定温度从开氏度转换为华氏度的函数。由于0°K会尽可能冷,因此如果看到负温度,该函数将无法正常运行:

#!/usr/bin/python3

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/python3

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/python3

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

例外条款


你还可以使用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语句并不是一种好的编程习惯,因为它会捕获所有异常,但不会使程序员识别可能出现的问题的根本原因。

具有多个例外的例外条款


你也可以使用相同的 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.

最后审判条款


你可以使用 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.
    ......................

Note :你可以提供except子句或finally子句,但不能同时提供。你不能使用 else 子句以及finally子句。

#!/usr/bin/python3

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")
    fh.close()

如果你无权以写入模式打开文件,则将产生以下结果:

Error: can't find file or read data

相同的示例可以更清晰地编写如下:

#!/usr/bin/python3

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")

这将产生以下结果:

Going to close the file

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

异常的论点


异常可以有一个 argument ,该值提供有关该问题的其他信息。参数的内容因异常而有所不同。你可以通过在except子句中提供变量来捕获异常的参数,如下所示:

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

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

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

以下是单个异常的示例:

#!/usr/bin/python3

# Define a function here.
def temp_convert(var):
    try:
        return int(var)
    except ValueError as 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 是exception参数的值。该参数是可选的;如果未提供,则异常参数为None。

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

异常可以是字符串,类或对象。 Python核心引发的大多数异常都是类,带有作为该类实例的参数。定义新的异常非常容易,可以执行以下操作:

def functionName( level ):
    if level <1:
        raise Exception(level)
        # The code below to this would not be executed
        # if we raise the exception
    return level

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

try:
    Business Logic here...
except Exception as e:
    Exception handling here using e.args...
else:
    Rest of the code here...

以下示例说明了引发异常的用法:

#!/usr/bin/python3

def functionName( level ):
    if level <1:
        raise Exception(level)
        # The code below to this would not be executed
        # if we raise the exception
    return level

try:
    l = functionName(-10)
    print ("level = ",l)
except Exception as e:
    print ("error in level argument",e.args[0])

这将产生以下结果

error in level argument -10

用户定义的异常


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

这是一个有关的例子 RuntimeError 。在这里,创建一个类,该类从 RuntimeError 。当你在捕获异常时需要显示更多特定信息时,此功能很有用。

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

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

因此,一旦定义了上述类,就可以引发异常,如下所示:

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