python - 在请求中发送多部分表单数据时是否需要使用 with 语句?

标签 python python-requests with-statement

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

Requests makes it simple to upload Multipart-encoded files:

>>> 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 语句。

最佳答案

tl;dr:您的直觉是正确的。


没有 with声明(或明确的 payload.close() 调用),您没有关闭文件。

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

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

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

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

以及使用 requests 做大量工作的程序种类往往正是需要处理数千个文件的程序类型,因此这可能是一个真正的问题。

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

关于python - 在请求中发送多部分表单数据时是否需要使用 with 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51973067/

相关文章:

python - 如何使用 Python 请求发送 AWS 凭证?

python - 如何使用 "with"调用 tempfile.mkstemp() ? - 或者为什么它不返回带有 __exit__() 的 fd?

C 表达式的 Python 等价物

python - 使用 python requests 库将文件发布到服务器时出现错误请求错误

python - 从线程(concurrent.futures)更改小部件的可见性,在正常模式下不起作用,在 Debug模式下它可以工作,为什么?

Python-requests 如何在发布前调用 js 函数计算一些值?

python - 在 Python 的调用代码中捕获 __enter__ 中的异常

python - 在 lambda 中使用上下文管理器,怎么样?

python - 与 Python 相对,用于 ... else

python - 在 Python 中,如何从一个或多个列表中删除重复项?