在Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们。正确关闭文件资源
的一个方法是使用try…finally:
1 | try: |
写try…finally非常繁琐。Python的with语句允许我们非常方便地使用资源,而不必担心资源没有关闭,
所以上面的代码可以简化为:
1 | with open('/path/to/file', 'r') as f: |
并不是只有open()函数返回的fp对象才能使用with语句。实际上,任何对象,只要正确实现了上下文管理,就可以用于with语句。
实现上下文管理是通过enter和exit这两个方法实现的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class Query(object):
def __init__(self, name):
self.name = name
def __enter__(self):
print('Begin')
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
print('Error')
else:
print('End')
def query(self):
print('Query info about %s...' % self.name)
#自己写的资源对象用于with语句
with Query('Bob') as q:
q.query()
所谓上下文关系是指: 先后执行顺序
@contextmanager
编写enter和exit仍然很繁琐,因此Python的标准库contextlib提供了更简单的写法,
上面的代码可以改写如下:
1 | from contextlib import contextmanager |
理解相当于装饰器 将函数进行包装、
很时候我们希望在执行某段代码的前后输出特定的字符 可以使用1
2
3
4
5
6
7
8
9@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)
with tag("h1"):
print("hello")
print("world")
输出
hello
world