Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
modul:m323:learningunits:lu03:callbacks [2024/09/11 09:13] – [Asynchron Programmieren in Python] kmaurizimodul:m323:learningunits:lu03:callbacks [2026/09/08 08:34] (aktuell) – Animation zur Umkehrung der Kontrolle eingebettet admin
Zeile 3: Zeile 3:
 Callback Funktionen sind eine klassische Anwendung von First-Class- und Higher-Order-Functions. Callback Funktionen sind eine klassische Anwendung von First-Class- und Higher-Order-Functions.
  
 +===== Animation: das Konzept hinter Callbacks =====
 +
 +Der erste Tab zeigt das Muster ohne jedes Framework: Ihre Funktion weiss, **was** geschehen soll, die fremde Funktion bestimmt, **wann** und **wie oft**. Man sieht die Übergabe nach unten und den Rückruf nach oben – und dass ein anderer Callback das Verhalten ändert, ohne dass am fremden Code etwas angepasst wird. Die beiden weiteren Tabs zeigen dasselbe Muster in echt: beim Button-Klick (samt dem Klammernfehler weiter unten) und beim nebenläufigen Warten.
 +
 +{{url>https://templates-python.github.io/m323_html/lu03/callbacks.html 100%,880px noborder|Animation: Callbacks, wer ruft wen und wann}}
  
 ===== Callbacks in der GUI Programmierung ===== ===== Callbacks in der GUI Programmierung =====
Zeile 35: Zeile 40:
  
 In diesem Beispiel ist ''on_button_click'' der Callback, der aufgerufen wird, wenn der Benutzer auf den Button klickt. In diesem Beispiel ist ''on_button_click'' der Callback, der aufgerufen wird, wenn der Benutzer auf den Button klickt.
 +
 +<WRAP center round tip 60%>
 +Achten Sie auf ''command=on_button_click'' – **ohne Klammern**. Die Funktion wird hier nicht aufgerufen, sondern nur //übergeben//. Mit ''command=on_button_click()'' würde die Funktion sofort beim Erstellen des Buttons einmal ausgeführt und dem Button anschliessend ihr Rückgabewert ''None'' übergeben – der Button täte danach beim Klicken gar nichts. Das ist einer der häufigsten Anfängerfehler in der GUI-Programmierung.
 +
 +Die beiden letzten Schritte im zweiten Tab der Animation oben zeigen genau diesen Fall.
 +</WRAP>
  
 ==== Fazit ==== ==== Fazit ====
Zeile 41: Zeile 52:
  
 ===== Callbacks in der Asynchronen Programmierung ===== ===== Callbacks in der Asynchronen Programmierung =====
 +
 +<WRAP center round info 60%>
 +Wir werden das asynchrone Programmieren nicht vertiefen am BZZ. Dies dürfen Sie dann an der Fachhochschule 😉
 +</WRAP>
 +
  
 Asynchrone Programmierung ist ein Ansatz, bei dem Operationen ausgeführt werden können, ohne den Ablauf des gesamten Programms zu blockieren. Ein häufiges Szenario für asynchrone Aufrufe sind Netzwerkanfragen, z. B. API-Aufrufe, bei denen nicht vorhersehbar ist, wie lange sie dauern werden. Asynchrone Programmierung ist ein Ansatz, bei dem Operationen ausgeführt werden können, ohne den Ablauf des gesamten Programms zu blockieren. Ein häufiges Szenario für asynchrone Aufrufe sind Netzwerkanfragen, z. B. API-Aufrufe, bei denen nicht vorhersehbar ist, wie lange sie dauern werden.
Zeile 90: Zeile 106:
     asyncio.run(main())     asyncio.run(main())
 </code> </code>
 +
 +Die Ausgabe zeigt, worum es geht – **beide** Tasks starten, bevor einer davon fertig ist:
 +
 +<code>
 +Task 1 gestartet
 +Task 2 gestartet
 +Task 1 abgeschlossen      (nach 2 Sekunden)
 +Task 2 abgeschlossen      (nach 3 Sekunden)
 +</code>
 +
 +Das ganze Programm dauert 3 Sekunden statt 5, weil die beiden Wartezeiten sich überlappen. Der dritte Tab der Animation oben zeigt diesen Ablauf auf einer Zeitachse, mit der sequenziellen Variante als Vergleich.
  
 === Beispiel: Asynchrone Dateioperation === === Beispiel: Asynchrone Dateioperation ===
Zeile 117: Zeile 144:
  
 Ein häufiges Problem bei Netzwerkanfragen ist die Notwendigkeit, eine maximale Wartezeit festzulegen. Dies kann durch die Verwendung von Timeout-Parametern und asynchroner Programmierung gelöst werden. Ein häufiges Problem bei Netzwerkanfragen ist die Notwendigkeit, eine maximale Wartezeit festzulegen. Dies kann durch die Verwendung von Timeout-Parametern und asynchroner Programmierung gelöst werden.
 +
 +Der Mock-Server antwortet erst nach 3 Sekunden (''mocky-delay=3000ms''), zugelassen sind aber nur 2 Sekunden (''timeout=2''). Dadurch wird der Fehlerzweig tatsächlich erreicht.
  
 <code python> <code python>
Zeile 125: Zeile 154:
     async with httpx.AsyncClient() as client:     async with httpx.AsyncClient() as client:
         try:         try:
-            response = await client.get('https://run.mocky.io/v3/685db531-06e7-4d66-bbf6-99de9f2feab3?mocky-delay=3000ms', timeout=5)+            response = await client.get('https://run.mocky.io/v3/685db531-06e7-4d66-bbf6-99de9f2feab3?mocky-delay=3000ms', timeout=2)
             print(response.text)             print(response.text)
         except httpx.RequestError as exc:         except httpx.RequestError as exc:
-            print(f'An error occurred while requesting data: {exc}')+            print(f'An error occurred while requesting data: {type(exc).__name__}') 
 +            # Ausgabe: An error occurred while requesting data: ReadTimeout
  
 async def main(): async def main():
Zeile 136: Zeile 166:
     asyncio.run(main())     asyncio.run(main())
 </code> </code>
 +
 +<WRAP center round tip 60%>
 +Zwei Details, die leicht übersehen werden:
 +
 +  * ''httpx.RequestError'' ist die Oberklasse aller Anfragefehler – ''ReadTimeout'' gehört dazu und wird von diesem ''except'' mitgefangen.
 +  * Bei einem Timeout ist ''str(exc)'' **leer**. Ein ''print(f''...: {exc}'')'' würde also eine abgeschnittene Meldung ohne jeden Hinweis ergeben. Deshalb wird hier ''type(exc).__name__'' ausgegeben.
 +
 +Setzt man ''timeout=5'', kommt die Antwort nach 3 Sekunden regulär an und der ''except''-Zweig wird nie erreicht.
 +</WRAP>
  
 === Beispiel: Daten von mehreren APIs gleichzeitig abrufen === === Beispiel: Daten von mehreren APIs gleichzeitig abrufen ===
Zeile 144: Zeile 183:
 import httpx import httpx
 import asyncio import asyncio
 +
  
 async def fetch_data(url): async def fetch_data(url):
     async with httpx.AsyncClient() as client:     async with httpx.AsyncClient() as client:
         response = await client.get(url)         response = await client.get(url)
-        return response.json()+        return response.text 
  
 async def main(): async def main():
Zeile 158: Zeile 199:
     for result in results:     for result in results:
         print(result)         print(result)
 +
  
 if __name__ == '__main__': if __name__ == '__main__':
Zeile 164: Zeile 206:
  
 Diese Beispiele zeigen verschiedene nützliche Anwendungsfälle für die asynchrone Programmierung in Python. Besonders bei I/O-intensiven Aufgaben hilft sie, die Blockierung des Programms zu vermeiden und die Gesamtleistung zu verbessern. Diese Beispiele zeigen verschiedene nützliche Anwendungsfälle für die asynchrone Programmierung in Python. Besonders bei I/O-intensiven Aufgaben hilft sie, die Blockierung des Programms zu vermeiden und die Gesamtleistung zu verbessern.
 +
 +----
 +{{tag>M323-LU03 M323-C2I M323-C2A}}
 +[[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi
  
  • modul/m323/learningunits/lu03/callbacks.1726038805.txt.gz
  • Zuletzt geändert: 2024/09/11 09:13
  • von kmaurizi