导航菜单

Python异常处理(二十六)

  Python异常处理(二十六)

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

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

  标准异常

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

  Python异常处理(二十六)

  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

  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