2009-05-19 4 views
2

haben diesen CodeWie ein Funktionswert mit Dekorateur zurückzukehren und Faden

import threading 
def Thread(f): 
    def decorator(*args,**kargs): 
     print(args) 
     thread = threading.Thread(target=f, args=args) 
     thread.start() 
     thread.join() 
    decorator.__name__ = f.__name__ 
    return decorator  

@Thread 
def add_item(a, b): 
    return a+b 


print(add_item(2,2)) 

aber die Funktion nie den Wert zurück, verlässt einen Weg, um die Rückkehr zu bekommen?

+0

Es sieht wie du den Thread startest und dich dann daran anschließt. Dies entspricht dem direkten Aufruf der Funktion add_item(). –

Antwort

4

Der Grund, None zurückgegeben wird, ist, weil gibt es nichts zurückzugeben (neben der Tatsache, dass decorator hat keine Rückgabeanweisung). join() gibt immer None, gemäß der documentation.

Ein Beispiel für die Kommunikation mit einem Thread finden Sie unter this email.

Wenn ich aber fragen darf: seit join() blockiert den aufrufenden Thread, was gibt es hier zu gewinnen?


Edit: ich um ein wenig gespielt, und das folgende ist eine Lösung, die nicht eine Warteschlange benötigt (nicht sagen, es ist eine bessere Lösung einfach anders.):

import threading 

# Callable that stores the result of calling the given callable f. 
class ResultCatcher: 
    def __init__(self, f): 
     self.f = f 
     self.val = None 

    def __call__(self, *args, **kwargs): 
     self.val = self.f(*args, **kwargs) 

def threaded(f): 
    def decorator(*args,**kargs): 
     # Encapsulate f so that the return value can be extracted. 
     retVal = ResultCatcher(f) 

     th = threading.Thread(target=retVal, args=args) 
     th.start() 
     th.join() 

     # Extract and return the result of executing f. 
     return retVal.val 

    decorator.__name__ = f.__name__ 
    return decorator 

@threaded 
def add_item(a, b): 
    return a + b 

print(add_item(2, 2)) 
2

Das ist, weil Sie nie einen Wert in Ihrer "Dekorateur" -Funktion zurückgeben.

Sie müssen eine gemeinsame Variable in Ihren Thread einfügen und den Rückgabewert Ihrer Thread-Funktion zurück in die "Decorator" -Funktion verschieben.