当前位置:首页>python>抛弃 try-finally:为什么 Python 大神的代码里,满屏都是 with?

抛弃 try-finally:为什么 Python 大神的代码里,满屏都是 with?

  • 2026-10-21 13:27:56
抛弃 try-finally:为什么 Python 大神的代码里,满屏都是 with?

<摘要>

生产环境里,很多“文件句柄耗尽”或“数据库连接池爆满”的事故,

并不是代码逻辑太复杂,而是异常发生时资源没有正确释放,

平时代码里,这类问题占了相当大的比例。

Python 中处理这类问题最简单有效的方式,就是用 with 语句,

它让资源自动管理,不容易出错。


1. 最容易出问题的写法
f = open('data.txt', 'w')f.write('Hello World')# 如果这行代码出错了,下面的 close 永远不会执行!do_something_complex() f.close()

文件没关,句柄一直占用,时间长了系统就会报错。

2. 加上 try-finally 的写法
f = open('data.txt', 'w')try:    f.write('Hello World')    do_something_complex()finally:# 无论是否报错,这里都会执行    f.close()

这样即使出异常,文件也会关闭。安全,但代码多几行,缩进也多,写起来不方便。

3. 用 with 的写法
withopen('data.txt', 'w') as f:    f.write('Hello World')    do_something_complex()# 出了缩进块,文件自动关闭。哪怕报错,也自动关闭。

with 块结束时,文件自动关闭。正常结束会关,抛异常也会关。代码短,逻辑清楚。

4、with 是怎么实现的
为什么 with 这么聪明?它到底在背后干了什么?
通俗点说,with 语句通过一种协议,强制对象必须遵守“进门登记”和“出门销户”的规则。
这涉及到两个特殊方法:
  • __enter__:进入 with 块时调用,通常用来获取资源(打开文件、连接数据库等)。

  • __exit__:离开 with 块时调用(不管正常结束还是异常),通常用来释放资源(关闭文件、断开连接等)。

你可以把它想象成酒店的“插卡取电”系统:
你进房间(Enter),插卡,通电;
你离开房间(Exit),拔卡,断电。
只要你人不在房间了,电一定会断。 这就是确定性。
5、 同时处理多个资源(Python 3.10+ 的写法)
在以前,如果你需要同时打开两个文件(比如把 A 文件内容读出来写入 B 文件),你可能会写嵌套:
# 旧时代的写法with open('input.txt') as fin:    with open('output.txt', 'w') as fout:        fout.write(fin.read())
这不仅难看,而且随着层级增加,代码会不断向右平移。
Python 3.10 引入了“带括号的上下文管理器” (Parenthesized context managers)。
# Python 3.10+ 新潮写法with (    open('input.txt', 'r') as fin,    open('output.txt', 'w') as fout):    fout.write(fin.read())

代码更平整,好读。建议用新写法。

6、 避坑指南
with 不创建作用域!
很多类似 C++ 或 Java 的语言,花括号 {} 内定义的变量在外部无法访问。但 Python 的 with 不同。所以变量名要避免和外面冲突。
with open('test.txt') as f:    content = "Secret Data"print(content)  # 竟然能打印出来!输出:Secret Dataprint(f)        # 文件对象也还在!(虽然已经处于 closed 状态)
#python#with
往期回顾BREAK AWAY
Pandas3.0用Rust重写后性能暴增5倍?
pandas 3.0 即将到来了!你必须知道的变化
2025年最受欢迎的编程语言:热度背后的逻辑与趋势
30个Python 经典操作,码农必看的实战技巧开场白

最新文章

随机文章