2010-08-15 5 views
8

Mam program, który pobiera informacje z innych stron i analizuje je za pomocą GetPage BeautifulSoup i Twisted. Później w programie wypisuję informacje, które tworzy odroczony proces. Obecnie mój program próbuje go wydrukować, zanim różniczka zwróci informacje. Jak mogę czekać?Uruchamianie programu Pythona do momentu, w którym Twisted odracza, zwraca wartość

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

czy naprawdę używasz 1 spacji na wcięcie ... –

+0

To był problem z formatowaniem tutaj, rzeczywisty kod wykorzystuje zakładkę –

Odpowiedz

8

Wygląda na to, że próbujesz uruchomić/uruchomić wiele reaktorów. Wszystko zostaje podłączone do reaktora z tym samym. Oto, jak użyć numeru DeferredList, aby poczekać na zakończenie wszystkich połączeń zwrotnych.

Należy również pamiętać, że twisAmaz zwraca wartość. Ta wartość jest przekazywana przez callbacksDeferredList i wychodzi jako value. Ponieważ DeferredList zachowuje porządek rzeczy, które są w nim umieszczane, możesz powiązać indeks wyników z indeksem numerów 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

Wygląda dobrze, dzięki Aaron! –

2

Po pierwsze, nie należy umieszczać metody reaktor.stop() w metodzie odroczonej, ponieważ zabija wszystko.

Teraz w Twisted "Czekanie" jest niedozwolone. Aby wydrukować wyniki twojego oddzwonienia, po prostu dodaj kolejne wywołanie zwrotne po pierwszym.

+0

Dzięki, Luc! Czy mogę zapytać, gdzie powinien iść reactor.stop()? –

+0

Kiedy powiedziałem, żebym nie wstawiał reaktora.stop(), chciałem nie umieszczać go w tym pierwszym odroczonym kodzie, ponieważ zatrzymałoby to wszystko. Powinieneś umieścić to w ostatnim odroczeniu (tym, który wydrukuje wyniki), gdzie jesteś pewien, że chcesz zatrzymać swój program. Tylko uwaga: powinieneś użyć addCallbacks (method1, error_method), aby złapać potencjalne błędy. –

+0

Spójrz na samouczek o odroczeniu na http://twistedmatrix.com/documents/current/core/howto/deferredindepth.html, szczególnie w sekcji o nazwie "Oddzwonienia mogą zwrócić odroczenia". –

Powiązane problemy