Python上下文管理器

Python中提供了一个contextlib的模块来帮助我们实现上下文管理操作。通过contextlib的contextmanager装饰器,可以把一个普通函数变成一个可以被with调用执行的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import contextlib


@contextlib.contextmanager
def worker_state(state_list, worker_thread):
print("------>", state_list, worker_thread)
try:
yield
finally:
print("------> finally")

free_list = ['P', 'S']
w_thread = "test"

with worker_state(free_list, w_thread):
print("######>", free_list)
print("######>", w_thread)


------------
------> ['P', 'S'] test
######> ['P', 'S']
######> test
------> finally

上述代码执行的顺序:

  • 代码走到第15行时,就去找被@contextlib.contextmanager装饰的worker_state函数
  • 执行第5行这个函数的函数体
  • 执行第6行得到结果------> ['P', 'S'] test
  • 执行到第8行时,暂停执行这个函数,回到with调用的代码块中继续执行
  • 执行第16行得到结果######> ['P', 'S']
  • 执行第17行得到结果######> test
  • with函数体执行完毕后,跳到被装饰的worker_state函数中,在yield行之后继续执行
  • 执行第10行得到结果------> finally

总结

@ontextlib.contextmanager装饰的函数,在被with调用时,首先执行这个函数的函数体,当在函数体内遇到yield时,跳出这个函数,去执行with下面的代码块,但with下面的代码块执行完毕时,会在跳回到函数中,继续执行yield下面的代码