有勇气的牛排博客

Python 上下文管理器与with语句详解

有勇气的牛排 15 Python 2025-08-02 22:35:18

1 什么是上下文管理器?

上下文管理器(Context Manager) 是一种实现了特定协议的对象,能够在进入上下文退出上下文时执行一些操作。

在 Python 中,只要一个对象实现了下面两个方法:

  • __enter__(self):进入上下文时调用。
  • __exit__(self, exc_type, exc_val, exc_tb):退出上下文时调用(无论是否发生异常都会执行)。

它就可以作为上下文管理器被 with 语句使用。

2 为什么要使用上下文管理器

在编程中,我们经常需要对资源进行成对操作,例如:

  • 打开文件后,必须关闭。
  • 获取锁后,必须释放。
  • 数据库连接,需要在使用完后关闭。
  • 网络连接,需要断开。

如果忘记释放资源,肯呢个会引发内存泄漏、死锁、文件句柄耗尽等问题。

上下文管理器可以自动帮我们完成清理工作,即使代码中途抛出异常也不影响。

3 with 语句的工作原理

with 语句的基本用法:

with 表达式 [as 变量]: 代码块

底层执行过程等价于:

manager = 表达式 exit_method = manager.__exit__ value = manager.__enter__() try: 代码块 except Exception as e: exit_method(type(e), e, e.__traceback__) raise else: exit_method(None, None, None)

也就是说:

  • __enter__() 用于初始化资源,并返回可用对象。
  • __exit__() 用于清理资源,不论是否出现异常都会执行。

4 常见场景

4.1 文件操作

with open("data.txt", "r", encoding="utf-8") as f: content = f.read()

好处:

  • 自动关闭文件
  • 异常安全

4.2 数据库连接

import sqlite3 with sqlite3.connect("test.db") as conn: cursor = conn.cursor() cursor.execute("CREATE TABLE IF NOT EXISTS user(id INT, name TEXT)");

即使SQL执行出错,也会自动提交或回滚事物,并关闭连接。

4.3 线程锁

import theading local = threading.Lock() with lock: # 临界区代码 pass # 自动释放锁

4.4 多个上下文

wiht open("input.txt") as fin, open("output.txt", "w") as fout: fout.write(fin.read())

5 自定义上下文管理器

5.1 使用类实现

# -*- coding: utf-8 -*- class MyContext: def __enter__(self): print("进入上下文") return "资源对象" def __exit__(self, exc_type, exc_val, exc_tb): print("退出上下文,清理资源") if exc_type: print("异常类型:", exc_type) print("异常值:", exc_val) print("异常追踪:", exc_tb) return True return False # 返回 False 表示异常会继续抛出 with MyContext() as res: print("使用资源对象:", res)

使用类实现Python上下文管理器

5.2 使用 contextlib.contextmanager 装饰器

# -*- coding: utf-8 -*- from contextlib import contextmanager @contextmanager def my_context_manager(): print('进入上下文') yield "资源对象" print('退出上下文,清理资源') with my_context_manager() as res: print(f"使用资源: {res}")

这种方式适合简单的上下文管理器编写。

6 面试高频考点

with常考的知识点:

  1. 本质是上下文管理器协议(__enter____exit__
  2. 典型应用场景(文件、数据库、锁、网络连接)
  3. 自定义实现方式(类实现/contextlib
  4. 异常处理机制(__exit__的返回值决定是否吞掉异常)

一句话总结:

with 就是“进入时准备好资源,退出时自动清理,不管中途是否出错,都会自动清理好资源”。

评论区

×
×