twisted.protocols.ftp.FTPClient和Deferreds

时间:2010-07-22 21:30:31

标签: python ftp twisted deferred

像大多数人一样,我已经花了一段时间才习惯使用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)

这是最好的方法吗?

1 个答案:

答案 0 :(得分:1)

  

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

我认为将客户端对象明确地作为参数传递确实是最好的方法 - 大多数情况下,它是多余的和优雅的。主要的替代方法是编写一个类并将客户端对象存储到一个实例变量中,这看起来有点麻烦;在我看来,为此目的使用全局变量是最不可取的选择(周围的全局变量越少越好! - )。