Python ftplib:如何正确释放连接对象?

时间:2017-09-26 14:31:38

标签: python ftp ftplib

我见过这样的代码(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

这是对的吗?

1 个答案:

答案 0 :(得分:1)

你确实在很大程度上回答了你自己的问题 正如评论中所讨论的那样,这是一个合法的问题,因为互联网“充斥着错误的代码示例”

为了澄清我的简短回答,这是一个遗留问题,其中Python3代码将无法在Python2上按预期执行。因此,互联网上的(好)示例有望包括对Python2中运行代码的危险性的解释。或者它们将使代码向后兼容一个小的修改。

这是一个实例,当代码在Python2上运行时,closing()用于模拟Python3中的新函数。

Python2(ftplib)没有__enter____exit__函数,因此渲染上下文句柄“无用”(除了使其向前兼容,更容易阅读IMO以及它已分配调用变量,在本例中为ftp) 为了使它无用,编写者在调用周围使用closing()来获得Python3的自动闭包。

如果您使用Python3 ,那么这是多余的,可能会降低您的代码速度(极少)。如果您不希望向后兼容,那么您可以跳过该特定代码。