Ich bin neu in Python und funktionaler Programmierung. Ich verwende Version 2.7.6Einen Wert aus einer Coroutine in Python ergeben, einen kA-Umwandler in einen Generator konvertieren
Ich verwende das Tornado-Framework, um asynchrone Netzwerkanforderungen zu erstellen. Von dem, was ich über die funktionale Programmierung gelernt habe, möchte ich, dass meine Daten mit Hilfe von Generatoren durch meinen Code strömen. Ich habe das meiste getan, was ich brauche, Generatoren zu verwenden und die Daten zu transformieren, während sie durch meine Funktionsaufrufe strömen.
Am Ende meines Streams möchte ich eine REST-Anforderung für einige Daten machen. Ich habe eine for-Schleife, kurz bevor ich meine Daten an Tornado übergebe, um den Pull zu initiieren und dann die http-Anfrage zu senden. Das von Tornado bereitgestellte http-Objekt nimmt eine Callback-Funktion als Option und gibt immer ein Future zurück - das eigentlich ein Tornado-Future-Objekt und nicht der offizielle Python-Future ist.
Mein Problem ist, dass, da ich jetzt Generatoren verwende, um meine Daten durch meinen Code zu ziehen, ich nicht mehr die Rückruffunktion verwenden möchte. Mein Grund dafür ist, dass nachdem ich meine Daten vom Rückruf zurückgeholt habe, meine Daten nun durch meinen Code geschoben werden und ich keine Generatoren mehr benutzen kann.
Mein Ziel ist es, eine Schnittstelle zu schaffen, die wie so erscheint:
urls = (...generated urls...)
responses = fetch(urls)
Wo Antworten ist ein Generator über den abgeschlossenen Urls.
Was ich versuchte - unter vielen Dingen - ist, die Ergebnisse vom Callback in einen Generator umzuwandeln. Ich habe über so etwas nachgedacht, obwohl ich weit davon entfernt bin, es für andere Themen zu implementieren, die ich bald erklären werde. Allerdings wollte ich meine Funktion holen so etwas wie folgt aussehen:
def fetch(urls):
def url_generator():
while True:
val = yield
yield val
@curry
def handler(gen, response):
gen.send(response)
gen = url_generator()
for u in urls:
http.fetch(u, callback=handler(gen))
return gen
ich auf das Problem der Code und Syntax konzentrieren vereinfacht, aber ich dachte, diese gut funktionieren würde. Meine Strategie war es, eine Coroutine/Generator zu definieren, an die ich die Antworten dann senden werde, wenn ich sie erhalte.
Am meisten Probleme habe ich mit der Coroutine/Generator. Selbst wenn ich einen Generator auf die obige Weise definiere und folgendes mache, bekomme ich eine Endlosschleife - das ist eines meiner Hauptprobleme.
def gen():
while True:
val = yield
print 'val', val
yield val
print 'after', val
break
g = gen()
g.send(None)
g.send(10)
for e in g:
print e
Dieser druckt val 10 after 10
im Koroutine wie bei der Pause erwartet, aber die for-Schleife wird nie den Wert von 10. Es hat nichts drucken, während der Pause gibt. Wenn ich die Pause entfernen, dann bekomme ich die unendliche Schleife:
val None
None
after None
None
val None
None
after None
None
...
Wenn ich die for-Schleife zu entfernen, dann wird die Koroutine nur drucken val 10
, wie es auf der zweiten Ausbeute wartet. Ich erwarte das. Die Verwendung führt jedoch zu nichts.
In ähnlicher Weise, wenn ich die For-Schleife entfernen und durch print next(g)
ersetzen, dann bekomme ich einen StopIteration-Fehler, der bedeutet, ich rief als nächstes auf einen Generator, der keine Werte mehr hatte.
Anywho, ich bin völlig verloren, während ich tiefer in Python stürze. Ich denke, das ist eine so häufige Situation in Python, dass jemand einen guten Ansatz kennt. Ich suchte nach "Callback in Generator konvertieren" und so, aber hatte nicht viel Glück.
Auf eine andere Anmerkung könnte ich möglicherweise jede Zukunft von der HTTP-Anfrage ergeben, aber ich hatte nicht viel Glück "warten" auf die Ausbeute für die Zukunft zu vervollständigen.Ich lese viel über 'yield from', aber es scheint Python 3 spezifisch zu sein und Tornado scheint noch nicht auf Python 3 zu funktionieren.
Vielen Dank für die Anzeige und danke für jede Hilfe, die Sie zur Verfügung stellen können.
Ehrfürchtig Frage :). Gut geschrieben und recherchiert. – Cyphase
Danke. Das ist meine erste Frage :) – Joe
Tornado funktioniert mit Python 3, Ist '@ curry' dein Generator? –