Zastanawiałem się, czy w Pythonie jest jakaś biblioteka do wywołań metod asynchronicznych . Byłoby wspaniale, gdybyś mógł zrobić coś takiego
@async
def longComputation():
<code>
token = longComputation()
token.registerCallback(callback_function)
# alternative, polling
while not token.finished():
doSomethingElse()
if token.finished():
result = token.result()
Lub asynchroniczne wywołanie procedury innej niż asynchroniczna
def longComputation()
<code>
token = asynccall(longComputation())
Byłoby wspaniale mieć bardziej wyrafinowaną strategię jako natywną w rdzeniu języka. Czy to było brane pod uwagę?
python
asynchronous
Stefano Borini
źródło
źródło
async
iawait
składnią od 3.5).Odpowiedzi:
Możesz użyć modułu wieloprocesorowego dodanego w Pythonie 2.6. Możesz użyć pul procesów, a następnie uzyskać wyniki asynchronicznie za pomocą:
Na przykład:
To tylko jedna alternatywa. Ten moduł zapewnia wiele udogodnień, aby osiągnąć to, czego chcesz. Poza tym naprawdę łatwo będzie zrobić z tego dekoratora.
źródło
from multiprocessing.dummy import Pool
. multiprocessing.dummy ma dokładnie to samo zachowanie zaimplementowane w wątkach zamiast w procesachCoś jak:
Więcej informacji można znaleźć w dokumentacji pod adresem https://docs.python.org/library/threading.html .
źródło
Od wersji Python 3.5 można używać ulepszonych generatorów dla funkcji asynchronicznych.
Ulepszona składnia generatora:
Nowa
async/await
składnia:źródło
Nie ma jej w rdzeniu językowym, ale bardzo dojrzałą biblioteką, która robi to, co chcesz, jest Twisted . Wprowadza obiekt Deferred, do którego można dołączyć wywołania zwrotne lub procedury obsługi błędów („errbacks”). Odroczona jest w zasadzie „obietnicą”, że funkcja ostatecznie przyniesie skutek.
źródło
Możesz zaimplementować dekorator, aby uczynić swoje funkcje asynchronicznymi, chociaż jest to trochę trudne.
multiprocessing
Moduł jest pełna małych dziwactw i pozornie arbitralnych ograniczeń - tym bardziej powód, aby ująć go za przyjazny interfejs, choć.Poniższy kod ilustruje użycie dekoratora:
W prawdziwym świecie rozwinąłbym nieco więcej na temat dekoratora, zapewniając sposób na wyłączenie go w celu debugowania (przy jednoczesnym utrzymaniu przyszłego interfejsu na miejscu) lub może ułatwienie radzenia sobie z wyjątkami; ale myślę, że to wystarczająco dobrze pokazuje zasadę.
źródło
Właśnie
źródło
Możesz użyć eventlet. Pozwala napisać coś, co wydaje się być kodem synchronicznym, ale działa asynchronicznie w sieci.
Oto przykład super minimalnego robota:
źródło
Moje rozwiązanie to:
I działa dokładnie zgodnie z życzeniem:
źródło
Coś takiego działa dla mnie, możesz wtedy wywołać funkcję, a ona wyśle się do nowego wątku.
źródło
Czy jest jakiś powód, aby nie używać wątków? Możesz skorzystać z
threading
klasy. Zamiastfinished()
funkcji użyjisAlive()
.result()
Funkcja mogłabyjoin()
wątku i pobrać wynik. Jeśli możesz, zastąp funkcjerun()
i,__init__
aby wywołać funkcję określoną w konstruktorze i zapisać wartość gdzieś w instancji klasy.źródło
Możesz użyć concurrent.futures (dodane w Pythonie 3.2).
źródło
Możesz użyć procesu. Jeśli chcesz go uruchamiać na zawsze, użyj funkcji while (jak w sieci):
jeśli chcesz go uruchomić tylko jeden raz, zrób tak:
źródło