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 [2026/08/18 10:17] – Kompetenz-Tags auf neue Kompetenzmatrix ZH gesetzt adminmodul: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 95: 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 122: 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 130: 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 141: 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 175: Zeile 209:
 ---- ----
 {{tag>M323-LU03 M323-C2I M323-C2A}} {{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.1787041045.txt.gz
  • Zuletzt geändert: 2026/08/18 10:17
  • von admin