def read_file():
try:
f = open('yui', 'r')
print ''.join(f.readlines())
except:
print 'error occurs while reading file'
finally:
f.close()
f
是在 try
块中定义的, 而在 finally
中无法引用.如果将
f
提取到 try
块外部, 如def read_file():
f = open('azusa', 'r')
try:
print ''.join(f.readlines())
except:
print 'error occurs while reading file'
finally:
f.close()
挫一点的方法自然是, 再套一层
try
吧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 'error occurs while reading file'
正规一点的方式是, 使用 Python 引入的
with
结构来解决, 如def readFile():
try:
with open('mio', 'r') as f:
print ''.join(f.readlines())
except:
print 'error occurs while reading file'
except
到; 否则, 在 with
块结束之后, 打开的文件将自动关闭.除了打开文件, 还有其它这样可以用于
with
的东西么? 或者说, 怎么自定义一个什么东西, 让它能用于 with
呢?直接回答后一个问题吧, 秘密在于 Python 虚拟机在
with
块退出时会去寻找对象的 __exit__
方法并调用它, 把释放资源的动作放在这个 __exit__
函数中就可以了; 另外, 对象还需要一个 __enter__
函数, 当进入 with
块时, 这个函数被调用, 而它的返回值将作为 as
后引用的值. 一个简单的例子是class Test:
def __init__(self):
print 'init'
def __enter__(self):
print 'enter'
return self
def __exit__(self, except_type, except_obj, tb):
print except_type
print except_obj
import traceback
print ''.join(traceback.format_tb(tb))
print 'exit'
return True
with Test() as t:
raise ValueError('kon!')
init
enter
<type 'exceptions.ValueError'>
kon!
File "test.py", line 17, in <module>
raise ValueError('kon!')
exit
__exit__
函数接受三个参数, 分别是异常对象类型, 异常对象和调用栈. 如果 with
块正常退出, 那么这些参数将都是 None
. 返回 True
表示发生的异常已被处理, 不再继续向外抛出.简单的介绍到此为止, 详细的情况可以参考 PEP 343 (这数字真不错, 73).