2010-08-15 88 views
8

我有一個程序,從其他頁面獲取信息並使用BeautifulSoup和Twisted的getPage解析它們。稍後在程序中打印延遲進程創建的信息。目前我的程序試圖在不同的返回信息之前打印它。我怎樣才能讓它等待?使python程序等待,直到扭曲延遲返回值

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 
+0

你真的使用1空格縮進... – 2010-08-15 19:30:31

+0

這是一個格式問題在這裏,實際的代碼使用標籤 – 2010-08-15 22:24:32

回答

8

看起來你正在試圖製造/運行多個反應堆。一切都被附加到同樣的反應堆。以下是如何使用DeferredList等待所有回調完成。

另請注意,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() 
+0

看起來不錯,謝謝Aaron! – 2010-08-15 20:36:41

2

首先,你不應該在你的延期方法中放一個reactor.stop(),因爲它會殺死所有的東西。

現在,在扭曲,「等待」是不允許的。要打印回調結果,只需在第一個回調之後添加另一個回調。

+0

謝謝,呂克!我可以問一下reactor.stop()應該在哪裏? – 2010-08-15 19:39:18

+0

當我說沒有放置一個reactor.stop()時,我的意思是不把它放在第一個延期代碼中,因爲它會阻止一切。 所以你應該把它放在最後延遲(打印結果的那個),你確定你想停止你的程序。 請注意:您應該使用addCallbacks(method1,error_method)來捕捉潛在的錯誤。 – 2010-08-15 20:02:59

+0

查看http://twistedmatrix.com/documents/current/core/howto/deferredindepth.html上關於推遲的教程,特別是名爲「回調可以返回延遲」的部分。 – 2010-08-15 20:09:03