Diese Frage ist schon ziemlich alt, aber ich wollte eine einfache Lösung vorstellen, die sich für mich bewährt hat und meinen Entwicklungsprozess unterstützt.
Die Methodik hinter dieser Antwort ist die Tatsache, dass die "neue" Zielfunktion, inner
ist die Zuweisung des Ergebnisses der ursprünglichen Funktion (übergeben durch die __init__
Funktion) zum result
Instanzattribut des Wrappers durch etwas, das Closure genannt wird.
Dadurch kann die Wrapper-Klasse den Rückgabewert aufbewahren, auf den der Aufrufer jederzeit zugreifen kann.
HINWEIS: Diese Methode muss keine manipulierten Methoden oder privaten Methoden der threading.Thread
Klasse, obwohl Ertragsfunktionen nicht berücksichtigt wurden (OP erwähnte keine Ertragsfunktionen).
Viel Spaß!
from threading import Thread as _Thread
class ThreadWrapper:
def __init__(self, target, *args, **kwargs):
self.result = None
self._target = self._build_threaded_fn(target)
self.thread = _Thread(
target=self._target,
*args,
**kwargs
)
def _build_threaded_fn(self, func):
def inner(*args, **kwargs):
self.result = func(*args, **kwargs)
return inner
Zusätzlich können Sie pytest
(vorausgesetzt, Sie haben es installiert) mit dem folgenden Code, um die Ergebnisse zu demonstrieren:
import time
from commons import ThreadWrapper
def test():
def target():
time.sleep(1)
return 'Hello'
wrapper = ThreadWrapper(target=target)
wrapper.thread.start()
r = wrapper.result
assert r is None
time.sleep(2)
r = wrapper.result
assert r == 'Hello'