【发布时间】:2017-09-26 14:31:38
【问题描述】:
我见过这样的代码(Python 3 代码):
import ftplib
from contextlib import closing
with closing(ftplib.FTP()) as ftp:
有必要使用closing 方法吗?在一个有趣的answer 中,我们可以读到在数据库连接对象中,上下文管理器的__exit__ 方法不会关闭连接(至少对于SQLite 不会),而是提交一个事务。因此,必须使用closing 方法。
Python 的 FTP 类怎么样?
查看Python ftplib的sources,可以发现:
# Context management protocol: try to quit() if active
def __exit__(self, *args):
if self.sock is not None:
try:
self.quit()
except (OSError, EOFError):
pass
finally:
if self.sock is not None:
self.close()
quit 方法被调用,因此我认为我们不必为 Python 3 使用closing 方法。所以我们可以只使用:
with (ftplib.FTP()) as ftp:
由于 Python 2 中缺少 __exit__ 方法,因此 Python 2 代码需要 closing。
这对吗?
【问题讨论】:
-
你已经回答了你自己的问题:) 正如你所说,在 Python2 中。既没有
__enter__函数也没有__exit__函数,因为上下文句柄在进入或退出时不会做任何事情,除了在你的情况下分配变量ftp。所以这是一个继承和向后兼容的合规性事情。如果您对成为一名倒退忍者不感兴趣,可以跳过它。 -
@Torxed 由于互联网上充斥着不正确的代码示例(我知道在许多一次性的小脚本中,您不需要为这些细节烦恼)一个很容易混淆,所以我想要确认。
-
这是一个非常好的问题 :) 我写了一个更长的答案,以防人们偶然发现这个问题。