大多數情況下,我需要一段時間才能習慣使用Deferreds,但我正在慢慢到達目的地。但是,我不清楚我如何處理響應,然後在使用Twisted的FTP模塊時使用處理後的響應調用另一個FTP命令。我使用example FTP code作爲我的跳板點。twisted.protocols.ftp.FTPClient和Deferreds
我想連接到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)
這是最好的方法嗎?
那麼這是扭曲世界中的常見模式?好,謝謝。 – pr1001 2010-07-23 09:09:09
@ pr1001,它並不是Twisted特有的:它基於回調(甚至在Python之外,例如在Javascript!中)的體系結構很常見。 – 2010-07-23 13:50:07
是的,我知道,但我希望Deferreds會給我一些魔法,以更程序化的方式進行編程(比如我在connectionMade中有兩個回調函數),同時仍然保持所有的異步特性。 – pr1001 2010-07-23 15:21:49