使python程序等待Twisted deferred返回值

2024-04-28 20:33:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个程序,可以从其他页面获取信息,并使用BeautifulSoup和Twisted的getPage解析它们。稍后在程序中,我打印延迟进程创建的信息。目前我的程序试图在differed返回信息之前打印它。我怎么能让它等?

def twisAmaz(contents): #This parses the page (amazon api xml file)
    stonesoup = BeautifulStoneSoup(contents)
    if stonesoup.find("mediumimage") == None:
       imageurl.append("/images/notfound.png")
    else:
      imageurl.append(stonesoup.find("mediumimage").url.contents[0])

    usedPdata = stonesoup.find("lowestusedprice")
    newPdata = stonesoup.find("lowestnewprice")
    titledata = stonesoup.find("title")
    reviewdata = stonesoup.find("editorialreview")

    if stonesoup.find("asin") != None:
        asin.append(stonesoup.find("asin").contents[0])
    else:
        asin.append("None")
    reactor.stop()


deferred = dict()
for tmpISBN in isbn:  #Go through ISBN numbers and get Amazon API information for each
    deferred[(tmpISBN)] = getPage(fetchInfo(tmpISBN))
    deferred[(tmpISBN)].addCallback(twisAmaz)
    reactor.run()

.....print info on each ISBN

Tags: 程序none信息ifcontentsfindappenddeferred
3条回答

看起来你在试着制造/运行多个反应堆。所有的东西都与相同的反应堆相连。下面是如何使用^{}等待所有回调完成的方法。

还要注意,twisAmaz返回一个值。这个值通过callbacksDeferredList传递,并以value的形式出现。由于DeferredList保持了放入其中的内容的顺序,因此可以将结果的索引与isbn的索引交叉引用。

from twisted.internet import defer

def twisAmaz(contents):
    stonesoup = BeautifulStoneSoup(contents)
    ret = {}
    if stonesoup.find("mediumimage") is None:
        ret['imageurl'] = "/images/notfound.png"
    else:
        ret['imageurl'] = stonesoup.find("mediumimage").url.contents[0]
    ret['usedPdata'] = stonesoup.find("lowestusedprice")
    ret['newPdata'] = stonesoup.find("lowestnewprice")
    ret['titledata'] = stonesoup.find("title")
    ret['reviewdata'] = stonesoup.find("editorialreview")
    if stonesoup.find("asin") is not None:
        ret['asin'] = stonesoup.find("asin").contents[0]
    else:
        ret['asin'] = 'None'
    return ret

callbacks = []
for tmpISBN in isbn:  #Go through ISBN numbers and get Amazon API information for each
    callbacks.append(getPage(fetchInfo(tmpISBN)).addCallback(twisAmazon))

def printResult(result):
    for e, (success, value) in enumerate(result):
        print ('[%r]:' % isbn[e]),
        if success:
            print 'Success:', value
        else:
            print 'Failure:', value.getErrorMessage()

callbacks = defer.DeferredList(callbacks)
callbacks.addCallback(printResult)

reactor.run()

另一个很酷的方法是使用@defer.inlineCallbacks。它允许您像编写常规顺序函数一样编写异步代码:http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks

首先,不应该在延迟的方法中放置reactor.stop(),因为它会杀死所有东西。

现在,在Twisted中,“等待”是不允许的。要打印回调的结果,只需在第一个回调之后添加另一个回调。

相关问题 更多 >