2017-09-21 9 views
2

Was ist ein eleganter/idiomatischer Weg, um etwas wie Tupel-Entpacken mit Futures zu erreichen?Python-Futures und Tupel-Entpacken

Ich habe Code wie

a, b, c = f(x) 
y = g(a, b) 
z = h(y, c) 

und ich möchte es konvertieren Futures zu verwenden. so etwas wie Im Idealfall würde Ich mag

a, b, c = ex.submit(f, x) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

Die erste Zeile, dass

TypeError: 'Future' object is not iterable 

wirft allerdings schreiben. Wie kann ich a,b,c bekommen, ohne 3 weitere ex.submit Anrufe tätigen zu müssen? dh. Ich möchte, um zu vermeiden, schreiben dies als:

import operator as op 
fut = ex.submit(f, x) 
a = client.submit(op.getitem, fut, 0) 
b = client.submit(op.getitem, fut, i) 
c = client.submit(op.getitem, fut, 2) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

Ich denke, eine mögliche Lösung ist es, eine unpack Funktion wie unten zu schreiben,

import operator as op 
def unpack(fut, n): 
    return [client.submit(op.getitem, fut, i) for i in range(n)] 

a, b, c = unpack(ex.submit(f, x), 3) 
y = ex.submit(g, a, b) 
z = ex.submit(h, y, c) 

, die funktioniert: zum Beispiel, wenn Sie zuerst definieren:

def f(x): 
    return range(x, x+3) 
x = 5 
g = op.add 
h = op.mul 

dann erhalten Sie

z.result() #===> 77 

Ich dachte, dass so etwas schon existieren könnte.


Das obige funktioniert nur mit dask.distributed.Future. Es funktioniert nicht für Ebene concurrent.futures.Future.

+1

Welcher Fehler? –

+0

@JohnZwinck 'TypeError: 'Future' -Objekt ist nicht iterierbar. –

+0

' operator.itemgetter' kann mehrere Elemente abrufen. Aber sieh dir seinen Code an. Es ist eine Klasse, die eine Iteration durchführt. – hpaulj

Antwort

2

Ein kurzer Blick auf:

https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future

schlägt vor, dass Sie etwas tun müssen, werden wie

afuture = ex.submit(f, x) 
a,b,c = afuture.result() 
... 

submit gibt ein Future Objekt, nicht das Ergebnis von f(x) läuft.

Diese SO Antwort zeigt an, dass Futures ist nicht trivial Chaining "Wirft einen Fehler"

How to chain futures in a non-blocking manner? That is, how to use one future as an input in another future without blocking?

+0

Die 'Zukunft.result() 'call blockiert den Aufruf von' f', was den Zweck der Verwendung von Futures zunichte macht. –

+0

@DanielMahler, können Sie uns ein Beispiel für die Verkettung ohne das Auspacken geben? Klingt, als hättest du mit "Futures" ein paar grundlegende Sachen gemacht. Erleuchte uns. Was sind diese 3 zusätzlichen Anrufe? – hpaulj