上下文管理器
with 语句原理、__enter__/__exit__、contextlib 装饰器
上下文管理器
with open(...) as f: — 这就是上下文管理器。它保证资源使用后一定释放,即使发生异常。
学完本章你将: 掌握 enter/exit、contextlib 装饰器、嵌套上下文。
自定义上下文管理器
python
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
if exc_type:
print(f"发生异常: {exc_val}")
return False # False = 不抑制异常
with FileManager("test.txt", "w") as f:
f.write("Hello")
# 自动关闭——即使 write 抛异常
@contextmanager 装饰器(更简洁)
python
from contextlib import contextmanager
@contextmanager
def timer(name):
import time
start = time.time()
yield # yield 前后 = enter/exit
print(f"{name} 耗时 {time.time() - start:.3f}s")
with timer("计算"):
sum(range(10_000_000))
嵌套与组合
python
from contextlib import ExitStack
# 动态管理多个上下文
with ExitStack() as stack:
files = [stack.enter_context(open(f"file{i}.txt", "w"))
for i in range(5)]
# 所有文件会在退出时自动关闭
常用内置上下文
python
# 临时重定向
with redirect_stdout(io.StringIO()) as buf:
print("被捕获")
result = buf.getvalue() # "被捕获\n"
# 临时目录
with tempfile.TemporaryDirectory() as tmp:
# 使用 tmp...
pass # 退出时自动删除