| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung |
| modul:m323:learningunits:lu02:purefunctions [2024/08/28 08:54] – [Beispiel 2] kmaurizi | modul:m323:learningunits:lu02:purefunctions [2026/08/25 09:47] (aktuell) – Animation zu Determinismus eingebunden admin |
|---|
| Unpure Functions, im Gegensatz zu pure functions, können Seiteneffekte haben oder von externen Zuständen abhängig sein. Sie können somit unerwartete Ergebnisse liefern, was sie schwerer zu verstehen und zu warten macht. | Unpure Functions, im Gegensatz zu pure functions, können Seiteneffekte haben oder von externen Zuständen abhängig sein. Sie können somit unerwartete Ergebnisse liefern, was sie schwerer zu verstehen und zu warten macht. |
| |
| | ==== Animation: Gleiche Eingabe – gleiches Ergebnis? ==== |
| | |
| | Die Animation ruft jeweils **dieselbe Funktion zweimal mit derselben Eingabe** auf – einmal mit globalem Zustand (Tab 1), einmal ohne (Tab 2). Achten Sie am Ende auf das Aufruf-Protokoll: In der Spalte «Eingabe» steht zweimal dasselbe. In der Ergebnisspalte nicht. |
| | |
| | {{url>https://templates-python.github.io/m323_html/lu02/pure-vs-unpure.html 100%,820px noborder|Animation: Pure und unpure Functions}} |
| |
| ==== Beispiel 1 ==== | ==== Beispiel 1 ==== |
| |
| Diese Funktion verändert den globalen Zustand (die Variable ''total'') und ist somit eine unpure function. Das ''global''-Schlüsselwort signalisiert dem Entwickler und dem Python-Interpreter, dass die Funktion eine globale Variable ändert. Dies macht es einfacher, "unpure" Funktionen zu erkennen und fördert die Verwendung von "pure" Funktionen, indem es die Aufmerksamkeit auf die Änderung des globalen Zustands lenkt. | Diese Funktion verändert den globalen Zustand (die Variable ''total'') und ist somit eine unpure function. Das ''global''-Schlüsselwort signalisiert dem Entwickler und dem Python-Interpreter, dass die Funktion eine globale Variable ändert. Dies macht es einfacher, "unpure" Funktionen zu erkennen und fördert die Verwendung von "pure" Funktionen, indem es die Aufmerksamkeit auf die Änderung des globalen Zustands lenkt. |
| | |
| | <WRAP center round tip 60%> |
| | **Zum Nachdenken:** Rufen Sie ''add_to_total(3)'' zweimal hintereinander auf. Beim ersten Mal ist ''total'' danach 3, beim zweiten Mal 6 – gleiche Eingabe, anderes Ergebnis. Genau das ist gemeint, wenn man sagt, eine unpure function sei //nicht deterministisch// (Tab 1 der Animation oben). |
| | </WRAP> |
| |
| ==== Beispiel 2 ==== | ==== Beispiel 2 ==== |
| |
| if __name__ == '__main__': | if __name__ == '__main__': |
| print('Vor der Änderung: ', my_list) # Output: Vor der Änderung: [1, 2, 3] | print('Vor der Änderung: ', my_list) # Output: Vor der Änderung: [1, 2, 3] |
| new_list = modify_list() | new_list = modify_list() |
| print('Neue Liste: ', new_list) # Output: Neue Liste: [1, 2, 3, 4] | print('Neue Liste: ', new_list) # Output: Neue Liste: None |
| print('Nach der Änderung: ', my_list) # Output: Nach der Änderung: [1, 2, 3, 4] | print('Nach der Änderung: ', my_list) # Output: Nach der Änderung: [1, 2, 3, 4] |
| </code> | </code> |
| |
| Wie Sie sehen können, ändert die Funktion ''modify_list'' den Zustand der ''my_list''. Daher ist ''modify_list'' eine unpure Funktion. In diesem Fall wird das ''global''-Schlüsselwort nicht benötigt, da Listen in Python "mutable" (veränderbar) sind. Das heißt, sie können innerhalb einer Funktion verändert werden, ohne dass das ''global''-Schlüsselwort benötigt wird. Das kann zu einer weniger klaren Code-Struktur führen, da es schwieriger ist, solche Änderungen auf den ersten Blick zu erkennen. | Wie Sie sehen können, ändert die Funktion ''modify_list'' den Zustand der ''my_list''. Daher ist ''modify_list'' eine unpure Funktion. In diesem Fall wird das ''global''-Schlüsselwort nicht benötigt, da Listen in Python "mutable" (veränderbar) sind. Das heißt, sie können innerhalb einer Funktion verändert werden, ohne dass das ''global''-Schlüsselwort benötigt wird. Das kann zu einer weniger klaren Code-Struktur führen, da es schwieriger ist, solche Änderungen auf den ersten Blick zu erkennen. |
| | |
| | <WRAP center round important 90%> |
| | **Achtung, häufige Fehlannahme:** ''new_list'' enthält **nicht** die geänderte Liste, sondern ''None''. Methoden wie ''append()'', ''sort()'' oder ''reverse()'' verändern die Liste //an Ort und Stelle// und geben bewusst ''None'' zurück – genau um zu signalisieren, dass hier mutiert und nicht neu erzeugt wird. Wer ''new_list = my_list.append(4)'' schreibt, verliert die Liste. |
| | </WRAP> |
| |
| ==== Beispiel 3 ==== | ==== Beispiel 3 ==== |
| |
| <code python> | <code python> |
| def append_to_list(some_list): | def append_to_list(some_list, append): |
| """ | """ |
| Appends the value 5 to the passed list. | Appends the value ''append'' to the passed list. |
| """ | """ |
| some_list.append(5) | some_list.append(append) |
| | |
| if name == 'main': | if __name__ == '__main__': |
| my_list = [1, 2, 3] | my_list = [1, 2, 3] |
| print('Vor der Änderung:', my_list) # Output: Vor der Änderung: [1, 2, 3] | print('Vor der Änderung:', my_list) # Output: Vor der Änderung: [1, 2, 3] |
| append_to_list(my_list) | append_to_list(my_list,5) |
| print('Nach der Änderung:', my_list) # Output: Nach der Änderung: [1, 2, 3, 5] | print('Nach der Änderung:', my_list) # Output: Nach der Änderung: [1, 2, 3, 5] |
| </code> | </code> |
| |
| ---- | ---- |
| {{tag>M323-LU02}} | {{tag>M323-LU02 M323-A1B}} |
| [[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 | [[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 |
| | |