错误
NameError
异常
EOFError:一个文件结尾(End of File)符号(由 ctrl-d 实现)在不该出现的时候出现了。
处理异常
try..except
try:
text = input('Enter something --> ')
except EOFError:
print('Why did you do an EOF on me?')
except KeyboardInterrupt:
print('You cancelled the operation.')
else:
print('You entered {}'.format(text))
输出:
# Press ctrl + d
Enter something --> Why did you do an EOF on me?
# Press ctrl + c
Enter something --> ^CYou cancelled the operation.
Enter something --> No exceptions
You entered No exceptions
如果没有任何错误或异常被处理,那么将调用 Python 默认处理器。
你还可以拥有一个 else
子句与 try..except 代码块相关联。else 子句将在没有发生异常的时候执行。
抛出异常
raise
语句来引发一次异常,具体方法是提供错误名或异常名以及要抛出(Thrown)异常的对象。
你能够引发的错误或异常必须是直接或间接从属于 Exception(异常) 类的派生类。
# encoding=UTF-8
class ShortInputException(Exception):
'''一个由用户定义的异常类'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try:
text = input('Enter something --> ')
if len(text) < 3:
raise ShortInputException(len(text), 3)
# 其他工作能在此处继续正常运行
except EOFError:
print('Why did you do an EOF on me?')
except ShortInputException as ex:
print(('ShortInputException: The input was ' +
'{0} long, expected at least {1}')
.format(ex.length, ex.atleast))
else:
print('No exception was raised.')
输出:
Enter something --> 'a'
ShortInputException: The input was 1 long, expected at least 3
Enter something --> 'abc'
No exception was raised.
自定义异常类型ShortInputException
Try … Finally
假设你正在你的读取中读取一份文件。你应该如何确保文件对象被正确关闭,无论是否会发生异常?这可以通过 finally 块来完成。
import sys
import time
f = None
try:
f = open("poem.txt")
# 我们常用的文件阅读风格
while True:
line = f.readline()
if len(line) == 0:
break
print(line, end='')
sys.stdout.flush()
print("Press ctrl+c now")
# 为了确保它能运行一段时间
time.sleep(2)
except IOError:
print("Could not find file poem.txt")
except KeyboardInterrupt:
print("!! You cancelled the reading from the file.")
finally:
if f:
f.close()
print("(Cleaning up: Closed the file)")
输出:
Programming is fun
Press ctrl+c now
^C!! You cancelled the reading from the file.
(Cleaning up: Closed the file)
使用 time.sleep
函数任意在每打印一行后插入两秒休眠,使得程序运行变得缓慢(在通常情况下 Python 运行得非常快速)。当程序在处在运行过过程中时,按下 ctrl + c 来中断或取消程序。
注意到 KeyboardInterrupt
异常被抛出,尔后程序退出。不过,在程序退出之前,finally
子句得到执行,文件对象总会被关闭。
另外要注意到我们在 print
之后使用了 sys.stout.flush()
,以便它能被立即打印到屏幕上。
with 语句
在 try
块中获取资源,然后在 finally
块中释放资源是一种常见的模式。因此,还有一个 with
语句使得这一过程可以以一种干净的姿态得以完成。
with open("poem.txt") as f:
for line in f:
print(line, end='')
程序输出的内容应与上一个案例所呈现的相同。
本例的不同之处在于我们使用的是 open
函数与 with
语句——我们将关闭文件的操作交由 with open
来自动完成。
在幕后发生的事情是有一项 with 语句所使用的协议(Protocol)。它会获取由 open 语句返回的对象,在本案例中就是“thefile”。
它总会在代码块开始之前调用 thefile.__enter__
函数,并且总会在代码块执行完毕之后调用 thefile.__exit__
。
因此,我们在 finally 代码块中编写的代码应该格外留心 __exit__
方法的自动操作。这能够帮助我们避免重复发显式使用 try..finally
语句。