Python基础 专题
您的位置:python > Python基础专题 > Python异常处理
Python异常处理
作者:--    发布时间:2019-11-20

python提供了两个非常重要的功能来处理python程序中的异常和错误,并在其中添加调试的函数功能 -

  • 异常处理 - 在本教程中介绍。这是一个列表标准python中提供的异常 - 标准异常。
  • 断言 - 在python 3教程中的断言中介绍。

标准异常

以下是python中可用的标准异常列表 -

编号 异常名称 描述
1 exception 所有异常的基类
2 stopiteration 当迭代器的next()方法没有指向任何对象时引发。
3 systemexit sys.exit()函数引发。
4 standarderror stopiterationsystemexit之外的所有内置异常的基类。
5 arithmeticerror 数据计算出现的所有错误的基类。
6 overflowerror 当计算超过数字类型的最大限制时引发。
7 floatingpointerror 当浮点计算失败时触发。
8 zerodivisonerror 对于所有的数字类型,当对零进行除数或模数时产生。
9 assertionerror assert语句失败的情况下引发。
10 attributeerror 在属性引用或分配失败的情况下引发。
11 eoferror 当没有来自raw_input()input()函数的输入并且达到文件结尾时引发。
12 importerror 导入语句失败时引发。
13 keyboardinterrupt 当用户中断程序执行时,通常按ctrl + c
14 lookuperror 所有查找错误的基类。
15 indexerror 当序列中没有找到索引时引发。
16 keyerror 当在字典中找不到指定的键时引发。
17 nameerror 当在本地或全局命名空间中找不到标识符时引发。
18 unboundlocalerror 当尝试访问函数或方法中的局部变量但未分配值时引发。
19 environmenterror 在python环境之外发生的所有异常的基类。
20 ioerror 在尝试打开不存在的文件时,输入/输出操作失败时触发,例如print语句或open()函数。
21 oserror 引起操作系统相关的错误。
22 syntaxerror 当python语法有错误时引发。
23 indentationerror 当缩进未正确指定时触发。
24 systemerror 当解释器发现内部问题时引发,但遇到此错误时,python解释器不会退出。
25 systemexit 当python解释器通过使用sys.exit()函数退出时引发。 如果没有在代码中处理,导致解释器退出。
26 typeerror 在尝试对指定数据类型无效的操作或函数时引发。
27 valueerror 当数据类型的内置函数具有有效参数类型时引发,但参数具有指定的无效值。
28 runtimeerror 产生的错误不属于任何类别时引发。
29 notimplementederror 当需要在继承类中实现的抽象方法实际上没有实现时引发。

python中的断言

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

  • 试想断言的最简单的方法就是将它与一个raise-if语句(或者更准确的说是一个加注if语句)相对应。测试表达式,如果结果为false,则会引发异常。

  • 断言由版本1.5引入的assert语句来执行,它是python的最新关键字。

  • 程序员经常在函数开始时放置断言来检查有效的输入,并在函数调用后检查有效的输出。

assert语句

当它遇到一个assert语句时,python会评估求值它的的表达式,是否为所希望的那样。 如果表达式为false,python会引发assertionerror异常。

assert的语法是 -

assert expression[, arguments]

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

示例

这里将实现一个功能:将给定的温度从开尔文转换为华氏度。如果是负温度,该功能将退出 -

#!/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:语句,然后是一个尽可能优雅地处理问题的代码块。

语法

下面是简单的语法try .... except ... else块 -

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:block中的代码不引发异常,则else块中的代码将执行。
  • else-block是一个不需要try:block保护的代码的地方。

示例

此示例打开一个文件,将内容写入文件,并且优雅地出现,因为完全没有问题 -

#!/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子句没有指定异常

也可以使用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语句捕获所有发生的异常。使用这种try-except语句不被认为是一个很好的编程实践,因为它捕获所有异常,但不会让程序员能更好地识别发生的问题的根本原因。

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

注意 - 可以提供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")

try块中抛出异常时,执行将立即传递给finally块。 在finally块中的所有语句都被执行之后,异常被再次引发,如果存在于try-except语句的下一个更高的层中,则在except语句中处理异常。

异常参数

一个异常可以有一个参数,参数它是一个值,它提供有关该问题的其他信息。 参数的内容因异常而异。 可以通过在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]]]

这里,exception是异常的类型(例如,nameerror),args是异常参数的值。 参数是可选的; 如果没有提供,则异常参数为none

最后一个参数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

注意 - 为了捕获异常,“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用于创建networkerror类的实例。

class networkerror(runtimeerror):
   def __init__(self, arg):
      self.args = arg

所以当定义了上面的类以后,就可以使用以下命令抛出异常 -

try:
   raise networkerror("bad hostname")
except networkerror,e:
   print e.args

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册