场景

资源是有限的,使用过后需要释放,否则会造成资源泄露

File

1
2
3
for x in range(10_000_000):
f = open('test.txt', 'w') # OSError: [Errno 24] Too many open files
f.write('hello')

context manager 帮助自动分配并释放资源 - with 语句

1
2
3
for x in range(10_000_000):
with open('test.txt', 'w') as f: # This will open and close the file 10_000_000 times
f.write('hello')

try - finally

1
2
3
4
5
f = open('test.txt', 'w')
try:
f.write('hello')
finally:
f.close() # close the file even if an exception occurs

Lock

try - finally

1
2
3
4
5
6
7
8
import threading

some_lock = threading.Lock()
some_lock.acquire()
try:
...
finally:
some_lock.release()

with

1
2
3
4
5
import threading

some_lock = threading.Lock()
with some_lock: # releases the lock when the block is exited
...

实现

基于的上下文管理器

image-20241102012321875

发生异常

image-20241102012631995

生成器

基于生成器的上下文管理器

image-20241102013504099

  1. 使用 contextlib.contextmanager 来定义基于生成器的上下文管理器,用来支持 with 语句
  2. file_manager() 函数是一个生成器
    • 执行 with 语句时,便会打开文件,并返回文件对象
    • 当 with 语句执行完毕后,执行 finally block 中关闭文件操作

选择

  1. 基于的上下文管理器和基于生成器的上下文管理器,两者在功能上是一致
  2. 基于的上下文管理器更加弹性,适用于大型系统
  3. 基于生成器的上下文管理器更加灵活,适用于中小型程序