Faire un programme python attendre jusqu'à ce que Twisted retours différé une valeur

StackOverflow https://stackoverflow.com/questions/3488854

  •  28-09-2019
  •  | 
  •  

Question

J'ai un programme qui va chercher les informations d'autres pages et Parsis en les utilisant BeautifulSoup et getPage de Twisted. Plus tard dans le programme d'information imprimer que le processus différé crée. Actuellement, mon programme tente d'imprimer avant le retour d'information de la différé. Comment puis-je attendre?

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
Était-ce utile?

La solution

Ce qu'il semble que vous essayez de faire / exécuter plusieurs réacteurs. Tout est attaché à la même réacteur. Voici comment utiliser un DeferredList attendre tous vos callbacks à la fin.

Notez également que twisAmaz retourne une valeur. Cette valeur est passée à travers le callbacks de DeferredList et sort comme value. Puisqu'un DeferredList conserve l'ordre des choses qui sont mises en, vous pouvez recouper l'indice des résultats avec l'index de vos numéros 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()

Autres conseils

Une autre façon cool de le faire est avec @ defer.inlineCallbacks. Il vous permet d'écrire du code asynchrone comme une fonction séquentielle régulière: http : //twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks

Tout d'abord, vous ne devriez pas mettre un reactor.stop () dans votre méthode différée, car il tue tout.

Maintenant, dans Twisted, "Waiting" est pas autorisé. Pour imprimer les résultats de vous rappel, il suffit d'ajouter un autre rappel après la première.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top