Python教程-Python 异常
当 Python 程序遇到错误时,它会停止执行程序的其余部分。在 Python 中,错误可能是表达式语法错误或 Python 异常。我们将看看什么是异常。此外,我们还将在本教程中看到语法错误和异常之间的区别。在此之后,我们将学习关于 try 和 except 代码块,以及如何引发异常和进行断言。之后,我们将查看 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 包含多个内置异常。然而,Python 提供了构建自定义异常的功能。
try 和 except 语句 - 捕获异常
在 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 子句中。在这个例子中,变量 i 的值大于 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 条件进行比较。如果表达式求值为假,则会引发异常。
通过 assert 语句进行断言,它在 Python 1.5 中作为最新的关键字添加。
通常在函数的开头使用断言来检查有效的输入,在调用函数之后检查有效的输出。
assert 语句
当找到 assert 语句时,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 子句的 try
Python 还支持 else 子句,在 try 和 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 关键字
Python 中有一个 finally 关键字,它总是在 try-except 块之后使用。无论是 try 块正常终止还是由于其他原因终止,finally 代码块始终会被执行。
以下是带有 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() 函数来访问不存在的文件,就会引发此异常。 |
21 | SyntaxError | 如果程序中出现语法错误,则引发此异常。 |
22 | IndentationError | 当我们进行不正确的缩进时,引发此异常。 |
23 | SystemExit | 如果使用 sys.exit() 方法终止 Python 解释器,则引发此异常。如果在代码中没有解决这种情况,解析器将退出。 |
24 | TypeError | 尝试执行不兼容的操作或函数时引发此异常。 |
25 | ValueError | 如果特定数据类型的内置方法的参数具有正确的类型但具有错误的值,则引发此异常。 |
26 | RuntimeError | 在程序执行期间发生无法分类的错误时引发此异常。 |
27 | NotImplementedError | 如果用户必须在继承类中定义的抽象函数没有定义,则引发此异常。 |
... | ... | ... |
总结
在了解了语法错误和异常之间的区别后,我们学习了不同的方法来引发、捕获和处理 Python 异常。我们在本教程中学到了以下这些子句:
- 我们可以使用 raise 关键字在代码的任何行引发异常。
- 使用 assert 关键字,我们可以检查特定条件是否满足,如果不满足,则引发异常。
- 在 try 子句中的所有语句都会被执行,直到发现异常为止。
- 通过 except 子句,可以检测并处理 try 代码块中的异常。
- 如果在 try 代码块中没有引发异常,我们可以在 else 代码块中编写将被 Python 解释器执行的代码。
以下是 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.