📜  Python异常处理

📅  最后修改于: 2020-12-23 05:20:48             🧑  作者: Mango


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

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

  • 断言-这将在Python断言教程中进行介绍。

标准例外列表-

Sr.No. Exception Name & Description
1

Exception

Base class for all exceptions

2

StopIteration

Raised when the next() method of an iterator does not point to any object.

3

SystemExit

Raised by the sys.exit() function.

4

StandardError

Base class for all built-in exceptions except StopIteration and SystemExit.

5

ArithmeticError

Base class for all errors that occur for numeric calculation.

6

OverflowError

Raised when a calculation exceeds maximum limit for a numeric type.

7

FloatingPointError

Raised when a floating point calculation fails.

8

ZeroDivisionError

Raised when division or modulo by zero takes place for all numeric types.

9

AssertionError

Raised in case of failure of the Assert statement.

10

AttributeError

Raised in case of failure of attribute reference or assignment.

11

EOFError

Raised when there is no input from either the raw_input() or input() function and the end of file is reached.

12

ImportError

Raised when an import statement fails.

13

KeyboardInterrupt

Raised when the user interrupts program execution, usually by pressing Ctrl+c.

14

LookupError

Base class for all lookup errors.

15

IndexError

Raised when an index is not found in a sequence.

16

KeyError

Raised when the specified key is not found in the dictionary.

17

NameError

Raised when an identifier is not found in the local or global namespace.

18

UnboundLocalError

Raised when trying to access a local variable in a function or method but no value has been assigned to it.

19

EnvironmentError

Base class for all exceptions that occur outside the Python environment.

20

IOError

Raised when an input/ output operation fails, such as the print statement or the open() function when trying to open a file that does not exist.

21

IOError

Raised for operating system-related errors.

22

SyntaxError

Raised when there is an error in Python syntax.

23

IndentationError

Raised when indentation is not specified properly.

24

SystemError

Raised when the interpreter finds an internal problem, but when this error is encountered the Python interpreter does not exit.

25

SystemExit

Raised when Python interpreter is quit by using the sys.exit() function. If not handled in the code, causes the interpreter to exit.

26

TypeError

Raised when an operation or function is attempted that is invalid for the specified data type.

27

ValueError

Raised when the built-in function for a data type has the valid type of arguments, but the arguments have invalid values specified.

28

RuntimeError

Raised when a generated error does not fall into any category.

29

NotImplementedError

Raised when an abstract method that needs to be implemented in an inherited class is not actually implemented.

Python断言

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

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

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

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

断言

当遇到断言语句时, Python评估附带的表达式,希望它是正确的。如果表达式为假,则Python引发AssertionError异常。

assert的语法是-

assert Expression[, Arguments]

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

这是将温度从开氏度转换为华氏度的函数。由于开氏温度为零,因此温度会尽可能低,因此如果看到负温度,该函数失效-

#!/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 
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:块中的代码未引发异常,则执行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

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. 

最后审判条款

您可以将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块中的所有语句后,如果在try-except语句的下一个更高层中存在,则再次引发异常,并在except语句中对其进行处理。

异常的论点

异常可以具有参数,该参数是提供有关问题的其他信息的值。参数的内容因异常而有所不同。您可以通过在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 [Exception [, args [, traceback]]]

在此, Exception异常的类型(例如NameError),而arguments是异常参数的值。该参数是可选的;如果未提供,则异常参数为None。

最后一个参数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还允许您通过从标准内置异常派生类来创建自己的异常。

这是与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