【问题标题】:twisted.protocols.ftp.FTPClient and Deferredstwisted.protocols.ftp.FTPClient 和 Deferreds
【发布时间】:2010-07-22 21:30:30
【问题描述】:

像大多数人一样,我需要一段时间才能习惯使用 Deferreds,但我正在慢慢适应。但是,我不清楚在使用 Twisted 的 FTP 模块时如何处理响应,然后调用另一个 FTP 命令使用处理后的响应。我使用example FTP code 作为我的起点。

我想连接到 FTP 服务器,获取所有顶级目录,然后输入每个目录并下载所有文件。

首先我连接:

creator = ClientCreator(reactor, FTPClient, config.opts['username'], config.opts['password'], passive=config.opts['passive'])
creator.connectTCP(config.opts['host'], config.opts['port']).addCallback(connectionMade).addErrback(connectionFailed)
reactor.run()

连接成功,所以我的connectionMade函数被调用:

def connectionMade(ftpClient):
    # Get a detailed listing of the current directory
    fileList = FTPFileListProtocol()
    d = ftpClient.list('.', fileList)
    d.addCallbacks(getSortedDirectories, fail, callbackArgs=(fileList,))
    d.addCallback(enterDirs)

如你所见,我排队getSortedDirectories,然后是enterDirs

def getSortedDirectories(result, fileListProtocol):
    # Go through all directories from greatest to least
    dirs = [directory for directory in sorted(fileListProtocol.files, reverse=True) if directory['filetype'] == 'd']
    return dirs

我的问题是,如何浏览enterDirs 中的目录?

def enterDirs(dirs):
    for directory in dirs:
        print "We'd be entering '%s' now." % directory

我是否应该将ftpClient 传递给enterDirs,就像将fileList 传递给getSortedDirectories 然后发出我的下载请求?

d.addCallback(enterDirs, callbackArgs=(ftpClient,))

def enterDirs(dirs, ftpClient):
    for directory in dirs:
        fileList = FTPFileListProtocol()
        d = ftpClient.list(directory, fileList)
        d.addCallbacks(downloadFiles, fail, callbackArgs=(directory, fileList, ftpClient))

def downloadFiles(result, directory, fileListProtocol, ftpClient):
    for f in fileListProtocol.files if f.filetype == '-':
        fileConsumer = FileConsumer()
        ftpClient.retrieveFile(os.path.join(directory['filename'], file['filename']), fileConsumer)

这是最好的方法吗?

【问题讨论】:

    标签: python ftp twisted deferred


    【解决方案1】:

    我应该将 ftpClient 传递给 像 fileList 这样的 enterDirs 被传递给 getSortedDirectories 然后让我的 下载请求? ……这是 最好的方法?

    我确实认为将客户端对象作为参数显式传递确实是最好的方法——主要是,它既节省又优雅。主要的替代方法是编写一个类并将客户端对象存储到一个实例变量中,这似乎有点麻烦;在我看来,为此目的使用全局变量将是最不可取的选择(周围的全局变量越少越好!-)。

    【讨论】:

    • 那么这就是 Twisted 世界的常见模式?好的,谢谢。
    • @pr1001,它并不是特别针对 Twisted:它在基于回调的架构中很常见(甚至在 Python 之外,例如在 Javascript 中!-)。
    • 是的,我知道,但我希望 Deferreds 能给我一些魔力,让我以更程序化的方式进行编程(比如我如何在 connectionMade 中对 Deferred 进行两次回调),同时仍然保持这一切都是异步的。
    • @pr1001,deferreds 允许您传递固定的额外参数,以便在调用时传递给每个回调——除此之外,您还需要“更多程序样式”吗?也许您可以编辑您的 Q 以添加一些您希望能够编写的“梦想世界代码”(当然不会在您背后发生黑魔法),以帮助我们向您展示如何实现它...?
    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    相关资源
    最近更新 更多