本文总结 Python
中常见的错误和异常以及对异常的处理,比如循环语句中的异常处理 1’ 2。
Updated: 2022 / 9 / 3
Python | 循环语句及其异常的处理
- 错误
- 语法
- 异常
- 处理
- 捕获预定义异常:Try 语句
- 抛出指定异常:raise
- 判断表达式并抛出异常:assert
- 参考链接
错误
Python
有两种错误很容易辨认,语法错误和异常 2。Python
assert
(断言)用于判断一个表达式,在表达式条件为 false
的时候触发异常。
语法
Python
的语法错误或者称之为解析错,是初学者经常碰到的。比如函数 print()
被检查到有错误,是它前面缺少了一个冒号 :
,语法分析器会指出出错的一行,并在最先找到的错误的位置标记了一个小小的箭头,如下所示:
while True
print('hi.')
# File "/Users/PycharmProjects/pythonProject0312/test.py", line 40
# while True
# ^
# SyntaxError: invalid syntax
异常
即便 Python
程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在 Python
无法正常处理程序时就会发生一个异常。大多数的异常都不会被程序处理,异常以不同的类型出现并作为错误信息的一部分,在终端中呈现。错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。
异常是 Python
对象,表示一个错误。当 Python
脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
异常的类型如下:
异常名称 | 描述 |
| 所有异常的基类 |
| 解释器请求退出 |
| 用户中断执行(通常是输入 |
| 常规错误的基类 |
| 迭代器没有更多的值 |
| 生成器 ( |
| 所有的内建标准异常的基类 |
| 所有数值计算错误的基类 |
| 浮点计算错误 |
| 数值运算超出最大限制 |
| 除(或取模)零 (所有数据类型) |
| 断言语句失败 |
| 对象没有这个属性 |
| 没有内建输入,到达 |
| 操作系统错误的基类 |
| 输入/输出操作失败 |
| 操作系统错误 |
| 系统调用失败 |
| 导入模块/对象失败 |
| 无效数据查询的基类 |
| 序列中没有此索引 ( |
| 映射中没有这个键 |
| 内存溢出错误 ( 对于 |
| 未声明/初始化对象 (没有属性) |
| 访问未初始化的本地变量 |
| 弱引用 ( |
| 一般的运行时错误 |
| 尚未实现的方法 |
| 语法错误 |
| 缩进错误 |
| 和空格混用 |
| 一般的解释器系统错误 |
| 对类型无效的操作 |
| 传入无效的参数 |
|
|
|
|
|
|
|
|
| 警告的基类 |
| 关于被弃用的特征的警告 |
| 关于构造将来语义会有改变的警告 |
| 旧的关于自动提升为长整型(long)的警告 |
| 关于特性将会被废弃的警告 |
| 可疑的运行时行为 ( |
| 可疑的语法的警告 |
| 用户代码生成的警告 |
异常的类型的结构如下:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
处理
参考这里 1。
捕获预定义异常:Try 语句
Exception
事件是执行代码时发生的事件。当错误发生时,Python
在执行过程中生成一个 exception
,exception
可被处理以避免中断你的代码 3。
比如,
a = 5
b = 0
print(a/b)
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject/example.py", line 25, in <module>
# print(a/b)
# ZeroDivisionError: division by zero
在上述代码中,系统无法以用0作除数,所以提出 exception
。
可以使用 try
, except
, else
和 finally
来处理 exception
:
语法如下:
try:
# Some Code....
# try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
# 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,try 子句余下的部分将被忽略。控制流就通过整个try语句(除非在处理异常时又引发新的异常)。一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
# 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
# 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
# 不要在 try 里写返回值。 try-except-else 里都是指做某事,而不是处理返回。如果在 try 里面写返回值,则 else 部分是 unreachable 的。
except:
# optional block
# Handling of exception (if required)
# 如果有 `Exception` 则在此区块对错误进行处理。可能存在多于一种 `Exception` 的情况。
# 但是如果此区块并未处理好 `Exception` 则其会被传入 `try` 外围的语句,导致代码的执行停滞;
# 如果没有 `Exception` 则执行 `Else` 部分的代码;
# 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,比如 `except (RuntimeError, TypeError, NameError):`
else:
# execute if no exception
# 如果没有 `Exception` 的发生则运行此区块的代码;
finally:
# Some code .....(always executed)
# 此区块总是会被执行,不管是否有 `Exception` 的产生。
# 值得注意地是,如果在 `finally` 语句中放入 `continue`,那么可能会有 `Exception` 逃逸到外围语句并造成代码执行终端。
以下面的例子为示例:
def divide(x, y):
try:
result = x // y
except ZeroDivisionError:
print("Sorry ! You are dividing by zero ")
else:
print("Yeah ! Your answer is :", result)
finally:
print('This is always executed')
divide(3, 2)
# Yeah ! Your answer is : 1
# This is always executed
divide(3, 0)
# Sorry ! You are dividing by zero
# This is always executed
抛出指定异常:raise
使用 raise
语句抛出一个指定的异常。
raise
语法格式如下:
raise [Exception [, args [, traceback]]]
# Exception 是异常的类型(例如,NameError)参数标准异常中任一种,args 是自已提供的异常参数。最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
以下面的例子为示例:
x = 10
if x > 5:
raise Exception(f'x 不能大于 5。\n但是 x 的值为: {x}')
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/text.py", line 43, in <module>
# raise Exception(f'x 不能大于 5。\n但是 x 的值为: {x}')
# Exception: x 不能大于 5。
# 但是 x 的值为: 10
raise
唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception
的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise
语句就可以再次把它抛出,如下所示:
try:
raise NameError('Hello world.')
except Exception as e:
print(f'Exception: {e}')
raise
Exception: Hello world.
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/text.py", line 42, in <module>
# raise NameError('Hello world.')
# NameError: Hello world.
判断表达式并抛出异常:assert
assert
(断言)用于判断一个表达式,在表达式条件为 false
的时候触发异常 4。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux
系统下运行,可以先判断当前系统是否符合条件。
assert
语法格式如下:
assert expression
等价于,
if not expression:
raise AssertionError
assert
后面也可以紧跟参数:
assert expression [, arguments]
等价于,
if not expression:
raise AssertionError(arguments)
以下面的例子为示例:
assert True # 条件为 true 正常执行
assert False # 条件为 false 触发异常
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/test.py", line 43, in <module>
# assert False # 条件为 false 触发异常
# AssertionError
assert 1 == 1 # 条件为 true 正常执行
assert 1 == 2 # 条件为 false 触发异常
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/test.py", line 51, in <module>
# assert 1 == 2 # 条件为 false 触发异常
# AssertionError
assert 1==2, '1 不等于 2'
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/test.py", line 59, in <module>
# assert 1==2, '1 不等于 2'
# AssertionError: 1 不等于 2
import sys
assert 'linux' in sys.platform, "该代码只能在 Linux 下执行"
# Traceback (most recent call last):
# File "/Users/PycharmProjects/pythonProject0312/test.py", line 63, in <module>
# assert 'linux' in sys.platform, "该代码只能在 Linux 下执行"
# AssertionError: 该代码只能在 Linux 下执行
参考链接