1

ほとんどの場合と同様に、Deferredの使用に慣れるのにしばらく時間がかかりますが、徐々にそこに到達しています。ただし、 TwistedのFTPモジュールを使用しているときに、応答を処理してから、処理された応答を使用して別のFTPコマンドを呼び出す方法がわかりません。出発点として、サンプルのFTPコードを使用しています。

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

likeftpClientに渡す必要がありますが、に渡されてからダウンロードリクエストを行いますか?enterDirsfileListgetSortedDirectories

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)

これが最善のアプローチですか?

4

1 に答える 1

1

fileListがgetSortedDirectoriesに渡されてからダウンロード要求を行うように、ftpClientをenterDirsに渡す必要がありますか?...これが最善のアプローチですか?

クライアントオブジェクトを引数として明示的に渡すことが実際に最善のアプローチだと思います。ほとんどの場合、それはスペアでエレガントです。主な代替手段は、クラスをコーディングし、クライアントオブジェクトをインスタンス変数に格納することです。これは少し面倒に思えます。私の意見では、目的のためにグローバル変数を使用することは、最も望ましくない代替手段です(周りのグローバルが少ないほど良いです!-)。

于 2010-07-22T23:57:24.517 に答える