1

次の関数を開始する前に 1 つの関数の結果が必要なので、複数の deferred を連鎖させています。ただし、最初の成功したコールバックの後でコードが壊れます。

class SaveContents(Protocol):
    def __init__(self, finished, filesize, filename):
        self.finished = finished
        self.remaining = filesize
        self.outfile = open(filename, 'wb')

    def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            self.outfile.write(display)
            self.remaining -= len(display)
        else:
            self.outfile.close()

    def connectionLost(self, reason):
        print 'Finished receiving body:', reason.getErrorMessage()
        self.outfile.close()
        self.finished.callback(None)

def cbRequest(response):
    print 'Response version:', response.version
    print 'Response code:', response.code
    print 'Response phrase:', response.phrase
    print 'Response headers:'
    print 'Response length:', response.length
    print pformat(list(response.headers.getAllRawHeaders()))
    finished = Deferred()
    response.deliverBody(SaveContents(finished, response.length, 'test2.pdf'))
    return finished

def cbShutdown(ignored):
    reactor.stop()

def addBarcodeChain(result, infile, outfile, analyze, duplex):
    print "starting Chain with results {0}".format(result)
    d = addBarcode(infile, outfile, lastStatement=result.headers.getHeader('lastStatement'), analyze=analyze, duplex=duplex)
    return d

def addBarcode(infile, outfile, **kwargs):
    """Send the pdf file to the remote server for processing, then save the results."""
    agent = Agent(reactor)
    f = open('70935.pdf', 'rb')
    body = FileBodyProducer(f)
    fstr = 'filename={0}'.format(infile)
    stmnt = 'lastStatement={0}'.format(kwargs['lastStatement'])
    duplex = 'duplex={0}'.format(int(kwargs['duplex']))
    analyze = 'analyze={0}'.format(int(kwargs['analyze']))
    options = '&'.join([fstr, stmnt, duplex, analyze])
    d = agent.request(
        'POST',
        'http://127.0.0.1:7777?{0}'.format(options),
        Headers({'User-Agent': ['Twisted Web Client Example'],
                 'Content-Type': ['multipart/form-data; boundary=1024'.format()]}),
        body)
    return d

#===============================================
# Main methods
#===============================================
def main(infiles, output_path, output_filename, analyze, duplex, debug):
    logger.info("Start of processing {0}".format(infiles))
    if debug:
        logger.setLevel(logging.DEBUG)

    lastStatement = 0
    work = []
    for globFile in infiles:
        for f in glob(globFile):
            outname = '{0}/{1}{2}.pdf'.format(output_path, os.path.splitext(os.path.basename(f))[0], output_filename)
            work.append( (f, outname) )

    d = addBarcode(work[0][0], work[0][1], lastStatement=lastStatement, analyze=analyze, duplex=duplex)
    d.addCallback(cbRequest)
    d.addErrback(cbShutdown)
    for f, outname in work[1:]:
        d.addCallback(addBarcodeChain, f, outname, analyze=analyze, duplex=duplex)
        d.addCallback(cbRequest)
        d.addErrback(cbShutdown)

    d.addCallback(cbShutdown)
    d.addErrback(cbShutdown)

    reactor.run()

私が理解できる限り、遅延再帰ループはcbRequest正しく機能するために必要ですが、将来のコールバックに結果を渡さないaddBarcodeChainため、結果の内容を使用しようとすると失敗します。

cbRequestまたはSaveContents、応答オブジェクトを将来のコールバックに転送するように調整するにはどうすればよいですか?

4

1 に答える 1

1

私はそれを考え出した。関連するビットは、私が推測したように、保存コンテンツ クラスです。

class SaveContents(Protocol):
    def __init__(self, finished, filesize, filename):
        self.finished = finished
        self.remaining = filesize
        self.outfile = open(filename, 'wb')

    def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            self.outfile.write(display)
            self.remaining -= len(display)
        else:
            self.outfile.close()

    def connectionLost(self, reason):
        print 'Finished receiving body:', reason.getErrorMessage()
        self.outfile.close()
        self.finished.callback(None)

特に、接続が閉じられると、connectionLost メソッドが呼び出されます。その場合、 を設定して、再帰的なコールバック ループを「クリーンアップ」する必要がありますself.finished.callback(None)

これを変更self.finished.callback(self.response)してinitメソッドに応答を渡すと、応答は将来のコールバックに渡されます。

class SaveContents(Protocol):
    def __init__(self, finished, response, filesize, filename):
        self.finished = finished
        self.remaining = filesize
        self.response = response
        self.outfile = open(filename, 'wb')

    def dataReceived(self, bytes):
        if self.remaining:
            display = bytes[:self.remaining]
            self.outfile.write(display)
            self.remaining -= len(display)
        else:
            self.outfile.close()

    def connectionLost(self, reason):
        print 'Finished receiving body:', reason.getErrorMessage()
        self.outfile.close()
        self.finished.callback(self.response)

これにより、後のコールバックが前のコールバックから取得されるという問題が解決されますNone

于 2012-07-19T20:15:36.143 に答える