10.1 异常处理
10.1.1 异常
即使语句或表达式在语法上是正确的,但在尝试执行时,它仍可能会引发错误。在执行时检测到的错误被称为异常。
大多数的异常都不会被程序处理,都以错误信息的形式显示出来,并终止程序。
例如:
>>> 10 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> num + 4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'num' is not defined
>>> int('abc')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'abc'
异常是Python对象,表示一个错误。当Python程序发生异常时我们需要捕获处理它,否则程序会终止执行。
10.1.2 异常处理
Python中异常处理的完整形式为:try-except-else-finally
try:
"包含可能会抛出异常的代码"
except:
"try代码块里的代码如果抛出异常了,该执行什么内容"
else:
"try代码块里的代码如果没有抛出异常,就执行这里"
finally:
"不管如何,finally里的代码,是总会执行的"
try语句按照如下方式工作:
首先,执行try语句块(在关键字try和关键字except之间的语句)
如果没有异常发生,忽略except语句块,try语句块执行后结束。
如果在执行try 子句时发生了异常,则跳过该子句中剩下的部分。然后,如果异常的类型和 except 关键字后面的异常匹配,则执行 except 子句 ,然后继续执行 try 语句之后的代码。
如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
一个 try 语句可能包含多个except语句块,分别来处理不同的特定的异常,但最多只有一个分支会被执行。
处理程序将只针对对应的try语句块中的异常进行处理,而不是其他的 try 的处理程序中的异常。
一个except语句块可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
except (RuntimeError, TypeError, NameError):
pass
最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。例如:10.1-异常.py
import sys
f = None
try:
f = open("myfile.txt")
except IOError:
print("Could not find file:myfile.txt")
except KeyboardInterrupt:
print("You cancelled the reading from the file.")
except BaseException:
print("Unexpected error:", sys.exc_info()[0])
raise
else:
while True:
line = f.readline()
if len(line) == 0:
break
print(line, end='')
finally:
if f:
f.close()
print("(Cleaning up: Closed the file)")
执行结果为:(假设没有要读取的myfile.txt文件)
Could not find file:myfile.txt
(Cleaning up: Closed the file)
完整结构中的else语句块是可选的,如果使用这个语句块,那么必须放在所有的except语句块之后。这个语句块将在try语句块没有发生任何异常的时候执行。
程序退出之前,finally语句块得到执行,文件对象总会被关闭。
Python中的 raise 语句用于主动抛出一个指定的异常。例如:
>>> raise(TypeError('just test'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: just test