Fare un programma Python attesa fino ritorto differita restituisce un valore
Domanda
Ho un programma che recupera informazioni da altre pagine e li analizza con BeautifulSoup e getPage Twisted. Più avanti nel programma di stampo informazioni che il processo differito crea. Attualmente il mio programma tenta di stamparlo prima che i rendimenti differivano le informazioni. Come posso fare è aspettare?
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
Soluzione
Quello che sembra è che stai cercando di fare / eseguire più reattori. Tutto viene attaccato al stesso reattore. Ecco come usare un DeferredList
di aspettare per tutti i callback alla fine.
Si noti inoltre che twisAmaz
restituisce un valore. Tale valore è passato attraverso il callbacks
DeferredList
ed esce come value
. Dal momento che un DeferredList
mantiene l'ordine delle cose che vengono messi in esso, si può attraversare riferimento l'indice dei risultati con l'indice dei tuoi codici 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()
Altri suggerimenti
Un altro modo intelligente per farlo è con defer.inlineCallbacks @. Esso consente di scrivere codice asincrono come una funzione sequenziale normale: http : //twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks
In primo luogo, non si dovrebbe mettere un reactor.stop () nel metodo differita, in quanto uccide tutto.
Ora, a torto, "Waiting" non è consentito. Per stampare i risultati di voi richiamata, basta aggiungere un altro richiamata dopo il primo.