由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:
def read_file():
try:
f = open('sawako', 'r')
try:
print(''.join(f.readlines()))
except:
print('error occurs while reading file')
finally:
f.close()
except:
print("rror occurs while reading file")
read_file()
执行结果:
rror occurs while reading file
这样的操作太麻烦了,可以通过with open语法来代替:
def readFile():
try:
with open('mio', 'r') as f:
print((''.join(f.readlines())))
except:
print('error occurs while reading file')
readFile()
执行结果与上例相同。这和前面的try ... finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。
底层原理
with语句的底层,其实是很通用的结构,允许使用上下文管理器(context manager)。上下文管理器实际是指一种支持__enter__
和__exit__
这两个方法的对象:
__enter__
方法是不带参数的,它会在进入with语句块时被调用,即将其返回值绑定到as关键字之后的变量上-
__exit__
方法则带有3个参数:异常类型、异常对象和异常回溯。在离开方法时这个函数会被调用(带有通过参数提供的,可以引发的异常)。如果__exit__
返回的是false,那么所有的异常都将不被处理
代码示例:
class OperateTest(object):
def open(self):
print("此处打开文件了!")
def close(self):
print("此处关闭文件了!")
def operate(self, txt_file):
print("文件处理中!%s" % txt_file)
def __enter__(self):
self.open()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
with OperateTest() as fp:
fp.operate("text_file")
执行返回结果:
此处打开文件了!
文件处理中!text_file
此处关闭文件了!
综上,文件是可以被用作上下文管理器。他们的enter方法返回文件本省对象,exit方法则关闭文件,也就是把我们的定义的方法,添加到系统默认调用的方法中进行二次封装,以此来达到简化代码的效果
网友评论