Reihe von Versprechen in Python

Abdul Mateen 21 Juni 2023
  1. Asynchrone Programmierung in Python
  2. Callback-Funktion
  3. versuchen/außer in Python
  4. Reihe von Versprechen in Python
Reihe von Versprechen in Python

In diesem Tutorial lernen wir, wie man eine Reihe von Versprechen in Python schreibt. Zuerst werden wir die asynchrone Programmierung in Python besprechen.

Als nächstes werden wir die Callback-Funktion in Python besprechen. Abschließend, bevor wir zum eigentlichen Thema kommen, gehen wir kurz auf try/except in Python ein und kommen dann zu einer Reihe von Promises in Python.

Asynchrone Programmierung in Python

Dieser Artikel erwartet, dass Sie eine grundlegende Vorstellung von Betriebssystem-Threads haben. Wenn Sie keine vorläufige Einführung in Threads haben, können Sie Threads in Betriebssystemen als Voraussetzung lesen.

Die asynchrone Programmierung ermöglicht die parallele Ausführung mehrerer Threads, während das Hauptprogramm (normalerweise Haupt-/Manager-Thread genannt) mehrere Worker-Threads erstellen kann. Typischerweise warten Hauptthreads auf Arbeitsthreads, die den Hauptthread nach Abschluss der Aufgabe informieren.

Im Gegensatz zur normalen Programmierung pausiert die asynchrone Funktion, anstatt die Kontrolle bis zum Wettbewerb zu behalten, und ermöglicht die parallele Ausführung anderer Funktionen (Threads).

Wir werden ein Beispiel für asynchrone Programmierung in Python diskutieren und geben; Es ist jedoch besser, zuerst einen verwandten synchronen Code zu sehen. Dieser Code wird dazu beitragen, das Verständnis durch Vergleich zu entwickeln.

def count():
    for i in range(5):
        print(i, end=" ")


def main():
    count()
    count()
    count()


main()

Hier rufen wir dreimal hintereinander die Funktion count auf. Die Leistung entspricht den Erwartungen.

0 1 2 3 4 0 1 2 3 4 0 1 2 3 4

Sie sehen die Ausgabe der ersten count-Funktion, gefolgt von der Ausgabe des zweiten Aufrufs der count-Funktion, gefolgt von der Ausgabe der letzten count-Funktion.

Die asyncio-Bibliothek von Python ermöglicht die Ausführung asynchroner Programme in Python. Die erste Anforderung für die asynchrone Programmierung besteht darin, Funktionen als erwartebare Objekte zu entwerfen.

Es gibt zwei Anforderungen, um eine Standardfunktion in ein erwartebares Objekt umzuwandeln. Die erste besteht darin, das Schlüsselwort async (vor dem Schlüsselwort def) zu verwenden, um asynchrone Funktionen anstelle von Routinefunktionen zu erstellen.

Die zweite Anforderung besteht darin, die Funktion sleep innerhalb asynchroner Funktionen aufzurufen, die aktuelle Funktion auszusetzen und andere Funktionen zu steuern.

Die sleep-Anweisung ist der spezifische Punkt im Code, an dem die Funktion genau in den Suspend-Zustand übergeht. Die zweite Anforderung der asynchronen Programmierung ist das Hinzufügen von await beim Aufrufen von erwartebaren Objekten (asynchrone Funktionen); andernfalls tritt ein Fehler auf.

Das Schlüsselwort await weist die Ereignisschleife an, die aktuelle Funktion auszusetzen, um anderen Funktionen Laufzeit zu geben.

Die dritte Anforderung besteht darin, die Funktion gather aufzurufen und erwartebare Objekte (asynchrone Funktionen) zu übergeben. Die gather-Funktion führt diese Funktionen in ihrer Reihenfolge, aber gleichzeitig aus.

Das bedeutet, dass zuerst die erste Funktion startet und nach einiger Zeit auch die zweite Funktion parallel startet. Ebenso werden alle asynchronen Funktionen gleichzeitig ausgeführt, eine nach der anderen.

Sehen wir uns nun den Code an.

import asyncio


async def count():
    for i in range(5):
        print(i, end=" ")
        await asyncio.sleep(0.5)


async def main():
    await asyncio.gather(count(), count(), count())


if __name__ == "__main__":

    asyncio.run(main())

Hier haben wir unseren bisherigen Code mit gewissen Ergänzungen auf asynchronen Code umgestellt. In der ersten Zeile wird die Bibliothek asyncio importiert.

Das Schlüsselwort async wird am Anfang aller Funktionen hinzugefügt.

Der Funktionsaufruf sleep wird der Funktion count hinzugefügt. Das Schlüsselwort await wird bei allen Funktionsaufrufen hinzugefügt, einschliesslich der Funktion main.

Zuletzt wird die gather-Funktion im main aufgerufen, wo die count-Funktion mehrfach aufgerufen wird, um jeden Funktionsaufruf als separaten Thread zu demonstrieren.

Mit der gather-Funktion fügen wir erwartebare Objekte hinzu, um eine Gruppe von asynchronen Funktionen zu bilden, die gleichzeitig ausgeführt werden. Sehen wir uns die Ausgabe dieses Codes an.

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4

In der Ausgabe können Sie sehen, dass alle Threads parallel ausgeführt werden und eine asynchrone Ausgabe erzeugen, anstatt vollständig ausgeführt zu werden.

Sie können mit dem mehrmaligen Aufrufen derselben Funktion verwechselt werden; Hier ist ein weiteres Beispiel, bei dem verschiedene Funktionen parallel ausgeführt werden.

import asyncio


async def count1():
    for i in range(10):
        print(i, end=" ")
        await asyncio.sleep(0.5)


async def count2():
    for i in range(50, 60):
        print(i, end=" ")
        await asyncio.sleep(0.5)


async def main():
    await asyncio.gather(count1(), count2())


asyncio.run(main())

Die Ausgabe dieses Codes ist:

0 50 1 51 2 52 3 53 4 54 5 55 6 56 7 57 8 58 9 59

Auch hier laufen beide Funktionen gleichzeitig.

Callback-Funktion

Ein Callback wird an eine andere Funktion (als Argument) übergeben. Die andere Funktion soll diese Funktion irgendwo in ihrer Definition zurückrufen.

Der Aufrufpunkt hängt jedoch davon ab, wie eine andere Funktion definiert ist.

Hier haben wir ein einfaches Codierungsbeispiel für die Callback-Funktion.

import random as r


def callback1(s):
    print(f"******* {s} *******")


def callback2(s):
    print(f"^^^^^^^ {s} ^^^^^^^")


def print_through_callback(message, f1, f2):
    if r.randint(0, 1) == 0:
        f1(message)
    else:
        f2(message)


def main():

    print_through_callback("Callback Example", callback1, callback2)


main()

In diesem Code hat unsere print-Funktion drei Parameter. Der zweite und dritte Parameter sind einige Funktionsnamen.

In main übergeben wir zwei Funktionen, und der Code ruft zufällig eine auf. Wenn Sie diesen Code mehrmals ausführen, können Sie sehen, dass beide Funktionen zufällig aufgerufen werden.

versuchen/außer in Python

Python bietet auch eine Ausnahmebehandlung. In Python haben wir einen try-Block, um den Code zu testen; es hat das Potenzial für eine Ausnahme, und im Block außer können Sie die Ausnahme behandeln.

Wir alle wissen, dass das Teilen durch Null nicht definiert ist und Programme (in fast jeder Programmiersprache) abstürzen; wenn wir die Division-durch-Null-Operation aufrufen. Wenn Sie keine Ahnung haben, versuchen Sie es mit diesem Code.

def main():
    x = int(input("Enter any number:"))
    print(2 / x)


main()

Geben Sie Null ein und sehen Sie sich das Ergebnis an; Ihr Programm wird abstürzen. Code-Abstürze sind eine schlechte Sache und sollten durch Ausnahmebehandlung vermieden werden.

Siehe den gleichen Code mit Ausnahmebehandlung.

def main():
    try:
        x = int(input("Enter any number:"))
        print(2 / x)
    except:
        print("Divide by zero is not defined")


main()

Sie sollten diesen Code ausführen und Werte ungleich Null eingeben; Sie erhalten das Ergebnis der Divisionsoperation, geschrieben in print (2/x); wenn Sie Null eingeben, gibt das Programm statt eines Absturzes die Meldung Dividieren durch Null ist nicht definiert aus.

Reihe von Versprechen in Python

Callback-Funktionen sind die gleichen wie normale Funktionen; ihre Verwendung unterscheidet sich jedoch.

Ziehen Sie umfangreiche Funktionen in Betracht, deren Ausführung viel Zeit in Anspruch nimmt. Normalerweise werden solche Funktionen asynchron gemacht.

Asynchrone Funktionen werden im Hintergrund ausgeführt und nach einer bestimmten Zeit abgeschlossen, während andere Funktionen parallel gestartet werden. Wenn Sie jedoch eine Funktion ausführen möchten, nachdem Sie eine schwergewichtige Funktion abgeschlossen haben, haben Sie die Wahl, die Callback-Funktion zu verwenden.

Es gibt jedoch ein Problem bei der Erledigung solcher Aufgaben. Was ist, wenn die Aufgabe vor Abschluss eine Ausnahme auslöst?

Um sicherzustellen, dass die Funktion nach erfolgreichem Abschluss der Aufgabe aufgerufen wird, sind Promises und asynchrone Programmierung erforderlich.

Versprechen

Ein Promise ist ein Objekt, das den erfolgreichen oder erfolglosen (Fehler) Abschluss einer asynchronen Funktion darstellt.

Promise-Objekte repräsentieren auch den resultierenden Wert aus der asynchronen Funktion. Ein Versprechen wird verwendet, um die Probleme im Zusammenhang mit mehreren Rückrufen zu verwalten.

Sie können promise API verwenden, um eine Reihe von Promises in Python auszuführen. Den gleichen Zweck können wir jedoch in Python durch async/await erreichen.

Für die Implementierung in Python mit asynchronen Funktionen müssen wir die Bibliothek asyncio mit asynchronen Funktionen verwenden. Wir können Funktionen nacheinander mit dem Schlüsselwort await aufrufen, das oben bereits beschrieben wurde.

Schließlich verwenden wir den try/except-Block. Sehen Sie sich zuerst den Code und die Ausgabe an.

Später werden wir den Zweck des try/except-Blocks erklären.

import asyncio
import random as r


async def f1(x):
    await asyncio.sleep(1)
    return x ** 2


async def f2(x):
    await asyncio.sleep(1)
    return x / 2


async def f3(x):
    if r.randint(0, 1) == 0:
        return x
    raise ValueError(x)


async def run():
    try:
        value = await f3(await f2(await f1(r.randint(5, 9))))
    except ValueError as exception:
        print("Exception Occurred:", exception.args[0])
    else:
        print("No Exception:", value)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    loop.close()

Das Folgende ist die kombinierte Ausgabe für das obige Python-Skript über 5 Läufe.

No Exception: 12.5
Exception Occurred: 12.5
Exception Occurred: 32.0
No Exception: 18.0
No Exception: 40.5

Die Ausgabe beschreibt nur, dass wir bei einigen asynchronen Vorgängen Erfolg oder Misserfolg haben können. Daher können wir nach dem Funktionsaufruf im try-Block eine Anweisung für die Callback-Funktion platzieren.

Bei erfolgreichem Abschluss führt der Code die Callback-Funktion aus. Bei einem Fehler geht die Steuerung zum Ausnahme-Block und ignoriert die Callback-Funktion.

Auf diese Weise können wir die Reihe von Promises in Python handhaben; Wenn wir einen erfolgreichen Abschluss haben, führen Sie die Callback-Funktion aus (die vom erfolgreichen Abschluss einer erforderlichen Aufgabe abhängt); Andernfalls müssen wir unsere Callback-Funktion nicht ausführen.