You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确关闭Python Requests的HTTP连接?会话关闭后仍可访问的疑问

Python Requests Session关闭逻辑解析

核心差异:Session上下文管理器 vs 文件对象上下文管理器

你产生困惑的核心在于requests.Session的上下文管理器行为和文件对象完全不同:

  • 文件对象在with块结束后,不仅释放底层文件I/O资源,还会让对象进入不可用状态,调用读写方法会直接报错。
  • 而requests.Session的with块,仅在退出时自动调用session.close()方法——这个方法的作用是关闭Session持有的连接池中所有空闲TCP连接,但不会销毁Session对象本身,也不限制你访问对象属性或再次调用请求方法。

你的代码解析

看这段测试代码:

import requests

with requests.Session() as s:
    s.post("https://example.com",  headers={'Connection':'close'})
    print(s)

print(s)
s.close()
print(s)

三次打印都输出同一个Session对象的内存地址,原因如下:

  1. print(s)只是输出对象的内存标识,只要对象未被Python垃圾回收,不管内部连接是否关闭都能正常打印。
  2. with块结束后,Session已经自动执行了close(),手动再调用一次s.close()属于重复操作,无额外效果。
  3. 若此时用这个Session再次发送请求(比如s.get("https://example.com")),请求依然会成功——因为Session在连接池为空时,会自动重新创建新的TCP连接。

另外要注意:你添加的headers={'Connection':'close'}是HTTP协议层面的指令,作用是告知服务器本次请求完成后关闭这条HTTP连接、不要复用。这和Session的连接池管理是两回事——它只会让当前请求的连接不被加入连接池复用,不会影响Session本身的状态。

验证Session连接是否真的关闭

若想确认Session的连接池是否已经关闭,可以查看其内部适配器的连接池状态:

import requests

with requests.Session() as s:
    s.get("https://example.com")
    # 获取HTTPS适配器的连接池
    adapter = s.adapters["https://"]
    print("with块内连接池数量:", len(adapter.poolmanager.pools))

# with块结束后,再次查看连接池
adapter = s.adapters["https://"]
print("with块外连接池数量:", len(adapter.poolmanager.pools))

运行后会看到,with块外的连接池数量为0,说明Session的连接池确实已被清空关闭,但Session对象本身依然可用。

为什么文件对象会报错?

文件对象的with块结束后,底层文件描述符已被操作系统回收,对象的所有I/O方法都会检查描述符有效性,一旦无效就抛出ValueError。而Session的close()只是清理连接池,没有给对象添加“不可用”标记,所以不会触发报错。

内容的提问来源于stack exchange,提问作者Simon Ernesto Cardenas Zarate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:30:59