【问题标题】:Do I need to use a with statement when sending multipart form data in requests?在请求中发送多部分表单数据时是否需要使用 with 语句?
【发布时间】:2026-02-12 15:05:02
【问题描述】:

在 Python 的 requests documentation 中,它建议像这样发送多部分表单数据:

Requests 让上传多部分编码文件变得简单:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}

>>> r = requests.post(url, files=files)

This question 显示相同的行为。但是,同一作者的this question 使用了with 声明:

with open('data','rb') as payload:
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    r = requests.post('https://IP_ADDRESS/rest/rest/2', auth=('userid', 'password'),
                      data=payload, verify=False, headers=headers)

我的直觉是在使用文件时我应该始终使用with 语句;在这种情况下我是否需要它?更清楚地说,我不是寻求关于是否使用 with 的建议。我特别指的是与requests 库的交互,如果我可以像文档暗示的那样省略with 语句。

【问题讨论】:

  • 我认为使用with 是一种自动关闭您在with-statement 中打开的连接的方法。你也可以不使用with,但是你需要明确地关闭连接,比如payload.close()。我想。
  • @downvoter 愿意发表评论吗?
  • @Ares 我不是反对者,但那个人可能会这样做,因为这是一个基于意见的问题。
  • @TylerH 我应该澄清一下;我问的是请求和with之间的交互,不是在寻求意见。

标签: python python-requests with-statement


【解决方案1】:

tl;dr:你的直觉是对的。


如果没有 with 语句(或明确的 payload.close() 调用),您不会关闭文件。

当然,您调用的某些函数(将文件作为参数传递)总是可能可能close 该文件。但总的来说,他们不会;尤其是requests.post 没有。 (由于这是非常罕见和不寻常的行为,如果一个函数这样做,它可能会被记录下来。但如果你需要绝对确定,你总是可以测试它——调用函数然后检查f.closed——或阅读源代码。 )

那么,如果你不关闭它会发生什么?它只是在那里打开,直到垃圾收集器删除文件对象。什么时候发生?好吧,你有一个名为files 的全局变量,它包含一个包含文件对象的字典。因此,在您退出程序之前,可以一直访问文件对象。它永远不会变成垃圾,所以它永远不会被删除,所以文件永远不会被关闭,直到你exit

由于您没有向文件写入任何内容,因此这不会导致任何可怕的事情,例如当您期望它在磁盘上时,未刷新的数据会留在缓冲区中。

但这确实意味着您在浪费资源。操作系统内核必须为每个打开的文件保留某种结构,并且进程需要一些其他东西来引用该内核结构。如果您打开数千个文件而不关闭它们,最终,其中一个表会填满,并且下次尝试打开文件时,您会收到有关打开的文件过多的错误。

requests 一起工作的程序类型往往正是需要处理数千个文件的程序类型,所以这可能是一个真正的问题。

那么,您需要在这里声明with 吗?也许不吧。但你肯定想要一个。

【讨论】:

  • 脚注对我来说是关键信息;我知道with 是如何工作的,但我不清楚如果requests 为我关闭或不关闭该资源,有多少有信誉的例子不使用它。
  • @Ares 好的,我编辑了答案以使脚注成为主要答案的一部分,并对其进行扩展。
【解决方案2】:

是的。使用with 语句为您处理关闭资源。您应该使用它来正确处理外部资源。

【讨论】:

    【解决方案3】:

    文档只是试图演示files 参数的工作原理,而不必过多担心文件是否被关闭。一个更好的例子是

    with open('report.xls', 'rb') as f:
        r = requests.post(url, files={'file': f})
    

    【讨论】:

      最近更新 更多