Lernen Sie die asynchrone Verarbeitung / Collouts von Python im Vergleich zu Node.js

Python ist eine Stilsprache, die die asynchrone Verarbeitung implementiert, indem das Modul "asyncio" importiert und Coroutinen definiert werden. Ein ** Collout ** ist eine Struktur, mit der die Verarbeitung unterbrochen und dann fortgesetzt werden kann, im Gegensatz zum ** Unterprogramm **, bei dem es sich um eine Struktur handelt, die erst nach Abschluss der Verarbeitung angehalten wird.

Konzentrieren wir uns diesmal darauf, wie die asynchrone Verarbeitung von Python anders geschrieben ist als die von Node.js "Promise" und "async / await", mit denen ich seit einiger Zeit vertraut bin. Überlegen.

Beachten Sie, dass der Python-Quellcode weitgehend mit der offiziellen Dokumentation Coroutines and Tasks übereinstimmt.

Corroutine

In Python definiert die Anweisung "async def" ein Collout.

Python


import asyncio

async def main():
    print('hello')
    await asyncio.sleep(1)
    print('world')

asyncio.run(main())

Dies ist ein Beispiel für das Drucken von "Welt" eine Sekunde nach dem Drucken von "Hallo". Sie können "Warten" im Collout verwenden. Dies ist ein typisches Beispiel für eine asynchrone Verarbeitung, bei der "Asyncio.sleep (1) warten" 1 Sekunde auf die Auflösung der Verarbeitung wartet und dann die nächste Verarbeitung startet.

Was ist mit Node.js? Erstens hat Node.js keine eingebaute asynchrone Funktion wie Pythons asyncio.sleep (),

function sleep(sec) {
  return new Promise(resolve => {
    setTimeout(resolve, timeout=sec*1000);
  })
}

(Im Folgenden wird die Definition dieser "Schlaf" -Funktion im Quellcode von Node.j weggelassen.) Dann können Sie wie folgt schreiben.

Node.js


async function main() {
  console.log('hello');
  await sleep(1);
  console.log('world');
}

main();

Wenn man die beiden vergleicht, ruft Pythons kolloutierte asynchrone Verarbeitung nicht einfach den Einstiegspunkt der obersten Ebene "main ()" auf, sondern "asyncio.run (main ())" wie "asyncio". Der Unterschied besteht darin, dass Sie darauf achten müssen, dass Sie es im Argument von .run () `ausführen.

Serielle Verarbeitung

Das Anordnen des Wartens führt zur seriellen Verarbeitung.

Python


import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    print(f"started at {time.strftime('%X')}")

    await say_after(1, 'hello')
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())

Dies ist ein Beispiel dafür, wie man 1 Sekunde wartet und dann "Hallo" druckt, dann weitere 2 Sekunden wartet und dann "Welt" druckt. In Node.js geschrieben, sollte es so aussehen:

Node.js


async function say_after(delay, what) {
  await sleep(delay);
  console.log(what);
}

async function main() {
  console.log(`started at ${new Date().toTimeString()}`);

  await say_after(1, 'hello');
  await say_after(2, 'world');

  console.log(`finished at ${new Date().toTimeString()}`);
}

main();

Es sieht genauso aus, ist also leicht zu verstehen.

Parallelverarbeitung

Mit Aufgaben können Sie Collouts in Python parallel ausführen.

Python


import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    task1 = asyncio.create_task(
        say_after(1, 'hello'))

    task2 = asyncio.create_task(
        say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    await task1
    await task2

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())

In diesem Beispiel wird im Gegensatz zum vorherigen Beispiel die Operation "2 Sekunden warten und dann" Welt "ausgeben" gleichzeitig mit der Operation "1 Sekunde warten und dann" Hallo "ausgeben" ausgeführt, also 1 als im vorherigen Beispiel. Es wird eine Sekunde früher enden. In Python können Sie mit asyncio.create_task () ein Collout als Task umschließen und seine Ausführung planen.

In Node.js geschrieben, sollte es so aussehen:

Node.js


async function say_after(delay, what) {
  await sleep(delay);
  console.log(what);
}

async function main() {
  const task1 = say_after(1, 'hello');
  const task2 = say_after(2, 'world');

  console.log(`started at ${new Date().toTimeString()}`);

  await Promise.all([task1, task2]);

  console.log(`finished at ${new Date().toTimeString()}`);
}

main();

Für Node.js können Sie "Promise.all ()" verwenden.


Schauen wir uns ein anderes Beispiel an.

Python


import asyncio

async def factorial(name, number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {name}: Compute factorial({i})...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {name}: factorial({number}) = {f}")

async def main():
    await asyncio.gather(
        factorial("A", 2),
        factorial("B", 3),
        factorial("C", 4),
    )

asyncio.run(main())

Dies ist eine Funktion, die die Leistung berechnet, indem die Multiplikation jedes Mal um 1 Sekunde verzögert wird. Dieses Mal kam asyncio.gather () heraus, aber dies plant auch das Argument Collout als Task.

In Node.js geschrieben, sollte es so aussehen:

Node.js


async function factorial(name, number) {
  let f = 1;
  for (let i=2;i<=number;++i) {
    console.log(`Task ${name}: Compute factorial(${i})...`);
    await sleep(1);
    f *= i;
  }
  console.log(`Task ${name}: factorial(${number}) = ${f}`);
}

async function main() {
  await Promise.all([
    factorial("A", 2),
    factorial("B", 3),
    factorial("C", 4)
  ]);
}

main();

Auszeit

In der asynchronen Python-Verarbeitung können Sie "asyncio.wait_for ()" verwenden, um es als Zeitüberschreitung zu behandeln, wenn die Verarbeitung in einer bestimmten Zeit nicht abgeschlossen ist.

Python


import asyncio

async def eternity():
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except asyncio.TimeoutError:
        print('timeout!')

asyncio.run(main())

Im obigen Beispiel läuft beispielsweise die Funktion "Ewigkeit ()", die 3600 Sekunden lang schläft, nach 1 Sekunde ab, ohne 3600 Sekunden zu warten.

Ich glaube nicht, dass es eine präzise Möglichkeit gibt, dies in Node.js zu implementieren (soweit ich weiß).

Wenn Sie "Promise.race ()" verwenden,

await Promise.race(eternity(), timeout(1.0))
  .catch(err => {
    console.log('timeout!');
  })

("Timeout (sec)" ist eine Funktion, die nach "sec" Sekunden "Zurückweisen" zurückgibt.) In dieser Implementierung wird das Warten auf "Ewigkeit ()" jedoch fortgesetzt, auch nachdem die Meldung "Timeout!" Nach 1 Sekunde angezeigt wird.

Siehe auch: Promise.race für Timeout-Versprechen verwenden

Caveat: Cleanup The timeout does not cause the other promise to clean up or cancel. For example, if a database-write promise were to be Promise.race ‘d against a timeout, and if the timeout completed first, then the database write operation would still be running and may (eventually) succeed, but the rest of your application will think it failed. Make sure to introduce logic to cancel the operation in case your application initiates a timeout. Handling cleanup and canceling logic is a tricky subject, as the feature is not built into JavaScript.

In diesem Sinne ist es in Python sehr praktisch, Unterbrechungen in der asynchronen Verarbeitung einfach schreiben zu können.

Recommended Posts

Lernen Sie die asynchrone Verarbeitung / Collouts von Python im Vergleich zu Node.js
Lerne Python mit ChemTHEATER
Kommunikationsverarbeitung durch Python
Bildverarbeitung mit Python
100 Sprachverarbeitungsklopfen mit Python 2015
"Apple-Verarbeitung" mit OpenCV3 + Python3
Akustische Signalverarbeitung mit Python (2)
Asynchrone Verarbeitung (Threading) in Python
[Python] Bildverarbeitung mit Scicit-Image
Verarbeiten Sie große Excel-Dateien mit Python, um die Produktivität zu verbessern
[Python] Einfache Parallelverarbeitung mit Joblib
100 Sprachverarbeitungsklopfen mit Python (Kapitel 1)
Paiza Python Primer 3: Loop-Verarbeitung lernen
Lerne Python durch Zeichnen (Turtle Graphics)
100 Sprachverarbeitungsklopfen mit Python (Kapitel 3)
Die Bildverarbeitung mit Python 100 klopft an die Binärisierung Nr. 3
[Python] Asynchrone Anfrage mit async / await
100 Bildverarbeitung mit Python Knock # 2 Graustufen
100 Sprachverarbeitung Knock Kapitel 1 von Python
Grundlagen der binärisierten Bildverarbeitung durch Python
Abrufen von Eigenschaftsinformationen durch Scraping mit Python
Bildverarbeitung mit Python 100 Knock # 10 Medianfilter
Erste Schritte mit Python3 # 1 Grundkenntnisse erlernen
Wiedereinführung in Python-Dekoratoren ~ Lernen wir Dekoratoren nach Typ ~
Socket-Kommunikation und Multithread-Verarbeitung durch Python
Bildverarbeitung durch Python 100 Knock # 1 Kanalersatz
Speichern Sie Videos Frame für Frame mit Python OpenCV
100 Bildverarbeitung mit Python Knock # 8 Max Pooling
Führen Sie regelmäßig eine beliebige Verarbeitung mit Python Twisted durch
Lassen Sie Heroku die Hintergrundverarbeitung mit Python durchführen
100 Sprachverarbeitungsklopfen mit Python (Kapitel 2, Teil 2)
Graustufen durch Matrix-Reinventor der Python-Bildverarbeitung-
3. Verarbeitung natürlicher Sprache durch Python 2-1. Netzwerk für das gleichzeitige Auftreten
Bildverarbeitung mit Python 100 Knock # 12 Bewegungsfilter
Bildverarbeitung mit Python 100 Knock # 6 Farbreduktionsverarbeitung
3. Verarbeitung natürlicher Sprache durch Python 1-1. Word N-Gramm
Python lernen! Vergleich mit Java (Grundfunktion)
100 Sprachverarbeitungsklopfen mit Python (Kapitel 2, Teil 1)
Zeichnen mit Matrix-Reinventor von Python Image Processing-
Verarbeiten Sie Bilder in Python ganz einfach mit Pillow
Organisieren Sie mit Python nach Ordnern getrennte Daten
Lernen Sie das Entwurfsmuster "Singleton" mit Python
Die Bildverarbeitung mit Python 100 führt zu einem durchschnittlichen Pooling von # 7
Leichte Bildverarbeitung mit Python x OpenCV
Lernen Sie das Designmuster "Facade" mit Python
Bildverarbeitung mit Python 100 Knock # 9 Gauß-Filter
Erste Schritte mit Python mit 100 Klopfen bei der Sprachverarbeitung
Asynchrone Verarbeitung in Python: Asyncio-Reverse-Referenz
Stock Number Ranking von Qiita Tag mit Python
3. Verarbeitung natürlicher Sprache durch Python 2-2. Koexistenznetzwerk [mecab-ipadic-NEologd]
So führen Sie eine Mehrkern-Parallelverarbeitung mit Python durch
Bildverarbeitung von Grund auf mit Python (5) Fourier-Transformation
Zeichnen Sie ein Diagramm, indem Sie es mit Pandas groupby verarbeiten
[Python] Ich habe mit der Verarbeitung natürlicher Sprache ~ Transformatoren ~ gespielt
Bildverarbeitung von Grund auf mit Python (4) Konturextraktion
Was vergleichst du mit Python und ==?
Asynchrone Verarbeitung mit Arduino (asynchrone Verarbeitung von Verarbeitungsanforderungen von Linux)
Bildverarbeitung mit Python 100 Knock # 11 Glättungsfilter (Durchschnittsfilter)
Parallele Verarbeitung ohne tiefe Bedeutung in Python