Python 异常处理

原文: https://thepythonguru.com/python-exception-handling/


于 2020 年 1 月 7 日更新


异常处理使您能够优雅地处理错误并对其进行有意义的处理。 如果未找到所需文件,则向用户显示一条消息。 Python 使用tryexcept块处理异常。

语法

  1. try:
  2. # write some code
  3. # that might throw exception
  4. except <ExceptionType>:
  5. # Exception handler, alert the user

如您在try块中看到的那样,您需要编写可能引发异常的代码。 当发生异常时,将跳过try块中的代码。 如果except子句中存在匹配的异常类型,则执行其处理器。

让我们举个例子:

  1. try:
  2. f = open('somefile.txt', 'r')
  3. print(f.read())
  4. f.close()
  5. except IOError:
  6. print('file not found')

上面的代码如下:

  1. 执行tryexcept块之间的第一条语句。
  2. 如果没有异常发生,则将跳过except子句下的代码。
  3. 如果文件不存在,则会引发异常,并且try块中的其余代码将被跳过
  4. 发生异常时,如果异常类型与except关键字后的异常名称匹配,则将执行该except子句中的代码。

注意

上面的代码仅能处理IOError异常。 要处理其他类型的异常,您需要添加更多的except子句。

try语句可以具有多个except子句,也可以具有可选的else和/或finally语句。

  1. try:
  2. <body>
  3. except <ExceptionType1>:
  4. <handler1>
  5. except <ExceptionTypeN>:
  6. <handlerN>
  7. except:
  8. <handlerExcept>
  9. else:
  10. <process_else>
  11. finally:
  12. <process_finally>

except子句类似于elif。 发生异常时,将检查该异常以匹配except子句中的异常类型。 如果找到匹配项,则执行匹配大小写的处理器。 另请注意,在最后的except子句中,ExceptionType被省略。 如果异常不匹配最后一个except子句之前的任何异常类型,则执行最后一个except子句的处理器。

注意

else子句下的语句仅在没有引发异常时运行。

注意

无论是否发生异常,finally子句中的语句都将运行。

现在举个例子。

  1. try:
  2. num1, num2 = eval(input("Enter two numbers, separated by a comma : "))
  3. result = num1 / num2
  4. print("Result is", result)
  5. except ZeroDivisionError:
  6. print("Division by zero is error !!")
  7. except SyntaxError:
  8. print("Comma is missing. Enter numbers separated by comma like this 1, 2")
  9. except:
  10. print("Wrong input")
  11. else:
  12. print("No exceptions")
  13. finally:
  14. print("This will execute no matter what")

注意

eval()函数允许 python 程序在其内部运行 python 代码,eval()需要一个字符串参数。

要了解有关eval()的更多信息,请访问 Python 中的eval()

引发异常


要从您自己的方法引发异常,您需要像这样使用raise关键字

  1. raise ExceptionClass("Your argument")

让我们举个例子

  1. def enterage(age):
  2. if age < 0:
  3. raise ValueError("Only positive integers are allowed")
  4. if age % 2 == 0:
  5. print("age is even")
  6. else:
  7. print("age is odd")
  8. try:
  9. num = int(input("Enter your age: "))
  10. enterage(num)
  11. except ValueError:
  12. print("Only positive integers are allowed")
  13. except:
  14. print("something is wrong")

运行程序并输入正整数。

预期输出

  1. Enter your age: 12
  2. age is even

再次运行该程序并输入一个负数。

预期输出

  1. Enter your age: -12
  2. Only integers are allowed

使用异常对象


现在您知道如何处理异常,在本节中,我们将学习如何在异常处理器代码中访问异常对象。 您可以使用以下代码将异常对象分配给变量。

  1. try:
  2. # this code is expected to throw exception
  3. except ExceptionType as ex:
  4. # code to handle exception

如您所见,您可以将异常对象存储在变量ex中。 现在,您可以在异常处理器代码中使用此对象。

  1. try:
  2. number = eval(input("Enter a number: "))
  3. print("The number entered is", number)
  4. except NameError as ex:
  5. print("Exception:", ex)

运行程序并输入一个数字。

预期输出

  1. Enter a number: 34
  2. The number entered is 34

再次运行程序并输入一个字符串。

预期输出

  1. Enter a number: one
  2. Exception: name 'one' is not defined

创建自定义异常类


您可以通过扩展BaseException类或BaseException的子类来创建自定义异常类。

python-exception-classes.jpg

如您所见,python 中的大多数异常类都是从BaseException类扩展而来的。 您可以从BaseException类或BaseException的子类(例如RuntimeError)派生自己的异常类。

创建一个名为NegativeAgeException.py的新文件,并编写以下代码。

  1. class NegativeAgeException(RuntimeError):
  2. def __init__(self, age):
  3. super().__init__()
  4. self.age = age

上面的代码创建了一个名为NegativeAgeException的新异常类,该异常类仅由使用super().__init__()调用父类构造器并设置age的构造器组成。

使用自定义异常类


  1. def enterage(age):
  2. if age < 0:
  3. raise NegativeAgeException("Only positive integers are allowed")
  4. if age % 2 == 0:
  5. print("age is even")
  6. else:
  7. print("age is odd")
  8. try:
  9. num = int(input("Enter your age: "))
  10. enterage(num)
  11. except NegativeAgeException:
  12. print("Only positive integers are allowed")
  13. except:
  14. print("something is wrong")

在下一篇文章中,我们将学习 Python 模块