Python 异常
当 Python 程序遇到错误时,会停止执行程序的剩余部分。Python 中的错误可能是表达式语法错误或 Python 异常。我们将看到异常是什么。此外,我们还将在本教程中看到语法错误和异常之间的区别。接下来,我们将学习如何尝试和捕获块,并如何引发异常和进行断言。之后,我们将看到 Python 异常列表。
什么是异常
在 Python 中,异常是在执行程序时发生的中断程序命令的事件。当 Python 代码遇到无法处理的条件时,它会引发异常。描述错误的 Python 对象称为异常。
当 Python 代码引发异常时,它有两个选项:立即处理异常或停止并退出。
异常与语法错误
当解释器发现语句有错误时,会发生语法错误。考虑以下情况:
代码
#Python code after removing the syntax error
string = "Python Exceptions"
for s in string:
if (s != o:
print( s )
输出:
if (s != o:
^
SyntaxError: invalid syntax
输出中的箭头显示了解释器遇到的语法错误的位置。在这种情况下,有一个未关闭的括号。关闭它并重新运行程序:
代码
#Python code after removing the syntax error
string = "Python Exceptions"
for s in string:
if (s != o):
print( s )
输出:
2 string = "Python Exceptions"
4 for s in string:
----> 5 if (s != o):
6 print( s )
NameError: name 'o' is not defined
我们在执行这段代码后遇到了一个异常错误。当Python代码在语法上是有效的但产生错误时,就会出现这种类型的错误。输出的最后一行给出了遇到的异常错误代码的名称。Python不仅显示”异常错误”,还显示了发生的异常错误的类型信息。在这种情况下,它是一个NameError。Python包含了几种内置的异常。然而,Python提供了构建自定义异常的功能。
尝试和捕获语句 – 捕获异常
在Python中,我们使用try和except代码块捕获异常并处理它们。try子句包含可能引发异常的代码,而except子句包含处理异常的代码行。让我们看看是否可以访问超过数组长度的索引,并处理由此产生的异常。
代码
# Python code to catch an exception and handle it using try and except code blocks
a = ["Python", "Exceptions", "try and except"]
try:
#looping through the elements of the array a, choosing a range that goes beyond the length of the array
for i in range( 4 ):
print( "The index and element from the array is", i, a[i] )
#if an error occurs in the try block, then except block will be executed by the Python interpreter
except:
print ("Index out of range")
输出:
The index and element from the array is 0 Python
The index and element from the array is 1 Exceptions
The index and element from the array is 2 try and except
Index out of range
在上面的示例中,潜在产生错误的代码块被插入到try子句内。超过2的值试图访问列表长度之外的项,导致异常。然后,except子句捕获此异常并在不停止它的情况下执行代码。
如何引发异常
如果一个条件不符合我们的要求,但根据Python解释器是正确的,我们可以使用raise关键字故意引发一个异常。我们可以与该语句一起使用自定义异常。
如果我们希望使用raise在发生给定条件时生成一个异常,可以按以下方式操作:
代码
#Python code to show how to raise an exception in Python
num = [3, 4, 5, 7]
if len(num) > 3:
raise Exception( f"Length of the given list must be less than or equal to 3 but is {len(num)}" )
输出:
1 num = [3, 4, 5, 7]
2 if len(num) > 3:
----> 3 raise Exception( f"Length of the given list must be less than or equal to 3 but is {len(num)}" )
Exception: Length of the given list must be less than or equal to 3 but is 4
实现停止并将异常显示在输出中,提供关于出错原因的指示。
Python中的断言
当我们完成程序验证时,断言是一种可以开关的一致性测试。
理解断言的最简单方法是将其与if-then条件进行比较。当计算表达式时,如果结果为false,则会引发异常。
断言是通过assert语句进行的,这是在Python 1.5中作为最新关键字添加的。
断言通常在函数的开头进行,用于检查输入的有效性,并在调用函数的末尾进行,用于检查输出的有效性。
assert语句
当Python在找到assert语句时检查相邻的表达式,最好是true。如果表达式的结果为false,则Python将引发AssertionError异常。
assert子句的语法是−
assert Expressions[, Argument]
Python使用ArgumentException作为AssertionError的参数,如果断言失败。我们可以使用try-except语句块来捕获和处理AssertionError异常,但如果没有处理,程序将停止,并且Python解释器将生成一条回溯信息。
代码
#Python program to show how to use assert keyword
# defining a function
def square_root( Number ):
assert ( Number < 0), "Give a positive integer"
return Number**(1/2)
#Calling function and passing the values
print( square_root( 36 ) )
print( square_root( -36 ) )
输出:
7 #Calling function and passing the values
----> 8 print( square_root( 36 ) )
9 print( square_root( -36 ) )
Input In [23], in square_root(Number)
3 def square_root( Number ):
----> 4 assert ( Number < 0), "Give a positive integer"
5 return Number**(1/2)
AssertionError: Give a positive integer
尝试使用else从句
Python还支持else从句,它应该放在try和except块中的每个except从句之后。只有当try块未引发异常时,Python解释器才会执行else块中的代码。
这是一个带有else从句的try块的示例。
代码
# Python program to show how to use else clause with try and except clauses
# Defining a function which returns reciprocal of a number
def reciprocal( num1 ):
try:
reci = 1 / num1
except ZeroDivisionError:
print( "We cannot divide by zero" )
else:
print ( reci )
# Calling the function and passing values
reciprocal( 4 )
reciprocal( 0 )
输出:
0.25
We cannot divide by zero
Python中的finally关键字
finally关键字在Python中可用,并且总是在try-except块之后使用。finally代码块始终在try块正常终止或由于其他原因终止后执行。
下面是一个带有try-except子句的finally关键字的示例:
代码
# Python code to show the use of finally clause
# Raising an exception in try block
try:
div = 4 // 0
print( div )
# this block will handle the exception raised
except ZeroDivisionError:
print( "Atepting to divide by zero" )
# this will always be executed no matter exception is raised or not
finally:
print( 'This is code of finally clause' )
输出:
Atepting to divide by zero
This is code of finally clause
用户定义的异常
通过继承典型的内置异常类,Python允许我们设计自定义的异常。
以下是一个RuntimeError的示例。在这种情况下,生成一个从RuntimeError派生的类。一旦检测到异常,我们可以使用它来显示额外的详细信息。
我们在try块中引发一个用户定义的异常,然后在except块中处理异常。使用变量var创建了一个名为EmptyError的类的示例。
代码
class EmptyError( RuntimeError ):
def __init__(self, argument):
self.arguments = argument
Once the preceding class has been created, the following is how to raise an exception:
Code
var = " "
try:
raise EmptyError( "The variable is empty" )
except (EmptyError, var):
print( var.arguments )
输出:
2 try:
----> 3 raise EmptyError( "The variable is empty" )
4 except (EmptyError, var):
EmptyError: The variable is empty
Python 异常列表
这是Python内置异常的完整列表。
序号 | 异常名称 | 异常描述 |
---|---|---|
1 | Exception | Python的所有异常都有一个基类。 |
2 | StopIteration | 如果迭代器的next()方法返回null,就会引发此异常。 |
3 | SystemExit | sys.exit()过程会引发此异常。 |
4 | StandardError | 除了StopIteration和SystemExit之外,这是所有Python内置异常的基类。 |
5 | ArithmeticError | 所有数学计算错误均属于此基类。 |
6 | OverflowError | 当计算超过数值数据类型的最大限制时,引发此异常。 |
7 | FloatingPointError | 如果浮点运算失败,就会引发此异常。 |
8 | ZeroDivisionError | 对于所有数值数据类型,在尝试除以零时引发此异常。 |
9 | AssertionError | 如果断言语句失败,将引发此异常。 |
10 | AttributeError | 如果变量引用或赋值失败,将引发此异常。 |
11 | EOFError | 当接近文件的末尾,并且解释器没有通过raw_input()或input()函数获得任何输入值时,将引发此异常。 |
12 | ImportError | 如果使用import关键字导入模块失败,将引发此异常。 |
13 | KeyboardInterrupt | 如果用户通过按下Ctrl+C来中断程序的执行,则引发此异常。 |
14 | LookupError | LookupErrorBase是所有搜索错误的基类。 |
15 | IndexError | 当尝试访问的索引未找到时,引发此异常。 |
16 | KeyError | 在要查找的字典中未找到给定的键时,引发此异常。 |
17 | NameError | 当变量不在本地或全局命名空间中时,引发此异常。 |
18 | UnboundLocalError | 当我们尝试在函数内访问一个本地变量,并且该变量没有被赋值时,引发此异常。 |
19 | EnvironmentError | 所有超出Python环境的异常都具有此基类。 |
20 | IOError | 如果输入或输出操作失败,比如使用print命令或open()函数访问不存在的文件时,引发此异常。 |
22 | SyntaxError | 每当程序发生语法错误时引发此异常。 |
23 | IndentationError | 当我们进行不正确的缩进时引发此异常。 |
24 | SystemExit | 当使用sys.exit()方法终止Python解释器时引发此异常。如果代码中未解决该情况,则解析器将退出。 |
25 | TypeError | 每当尝试执行与数据类型不兼容的操作或函数时引发此异常。 |
26 | ValueError | 如果特定数据类型的内置方法的参数是正确类型的,但是给出了错误的值,就会引发此异常。 |
27 | RuntimeError | 当程序执行过程中发生的错误无法分类时,会引发此异常。 |
28 | NotImplementedError | 如果在继承类中没有定义用户必须定义的抽象函数,则会引发此异常。 |
总结
在了解了语法错误和异常之间的区别后,我们学习了不同的方法来触发、捕获和处理Python异常。在本教程中,我们学习了以下几种异常处理机制:
- 我们可以使用raise关键字在代码的任意行抛出异常。
- 使用assert关键字,我们可以检查特定条件是否满足,如果不满足则抛出异常。
- 执行try子句中的所有语句,直到发现异常。
- 使用except函数检测和处理try子句中的异常。
- 如果try代码块中没有抛出异常,我们可以在else代码块中编写需要执行的代码。
下面是try、except、else和finally子句的语法。
语法:
try:
# Code block
# These statements are those which can probably have some error
except:
# This block is optional.
# If the try block encounters an exception, this block will handle it.
else:
# If there is no exception, this code block will be executed by the Python interpreter
finally:
# Python interpreter will always execute this code.