| Nächste Überarbeitung | Vorhergehende Überarbeitung |
| modul:m323:learningunits:lu02:purefunctions [2024/03/28 14:07] – angelegt - Externe Bearbeitung 127.0.0.1 | 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] |
| modify_list() | new_list = modify_list() |
| print('Nach der Änderung:', my_list) # Output: Nach der Änderung: [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] |
| </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 ==== |
| | |
| | In diesem Beispiel wird eine Liste als Argument an eine Funktion übergeben. Die Funktion modifiziert die Liste direkt, was zeigt, dass Listen in Python by reference übergeben werden. |
| | |
| | <code python> |
| | def append_to_list(some_list, append): |
| | """ |
| | Appends the value ''append'' to the passed list. |
| | """ |
| | some_list.append(append) |
| | |
| | if __name__ == '__main__': |
| | my_list = [1, 2, 3] |
| | print('Vor der Änderung:', my_list) # Output: Vor der Änderung: [1, 2, 3] |
| | append_to_list(my_list,5) |
| | print('Nach der Änderung:', my_list) # Output: Nach der Änderung: [1, 2, 3, 5] |
| | </code> |
| | |
| | In diesem Fall sehen wir, dass die Funktion ''append_to_list'' die Liste ''my_list'' ändert, indem sie ein weiteres Element hinzufügt. Obwohl ''my_list'' als Argument übergeben wird, wird es innerhalb der Funktion verändert, ohne dass es zurückgegeben werden muss. Das zeigt, dass die Liste by reference übergeben wird und Änderungen an der Liste in der Funktion Auswirkungen auf die ursprüngliche Liste außerhalb der Funktion haben. |
| | |
| | Dieses Verhalten macht ''append_to_list'' ebenfalls zu einer unpure function, da sie den Zustand der übergebenen Liste direkt verändert. |
| | |
| | <WRAP center round tip 60%> |
| | Wichtiger Hinweis: Dieses Beispiel verdeutlicht die Implikationen der Übergabe von mutable Objekten wie Listen in Python. Es ist wichtig zu verstehen, dass solche Änderungen schwer nachvollziehbar sein können, insbesondere in komplexeren Programmen, und das Verständnis des Unterschieds zwischen pure und unpure functions erleichtert es, vorhersehbaren und wartbaren Code zu schreiben. |
| | </WRAP> |
| |
| <WRAP center round tip 60%> | <WRAP center round tip 60%> |
| |
| ---- | ---- |
| {{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 |
| | |