6. Funktionen

6.1. Skript [fonc_01]: Gültigkeitsbereich von Variablen
Das Skript [fonc_01] zeigt Beispiele für den Gültigkeitsbereich von Variablen zwischen Funktionen:
Ergebnisse
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_01.py
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[1,30]
[i,j]=[2,0]
Process finished with exit code 0
Anmerkungen:
- Das Skript veranschaulicht die Verwendung der Variablen i, die in den Funktionen f1 und f2 als global deklariert wurde. In diesem Fall teilen sich das Hauptprogramm und die Funktionen f1 und f2 dieselbe Variable i.
6.2. Skript [fonc_02]: Geltungsbereich von Variablen
Das Skript [fonc_03] baut auf dem Skript [fonc_02] auf und zeigt, wie die Verwendung globaler Variablen vermieden werden kann:
Kommentare:
- Zeilen 2, 12: Anstatt global deklariert zu werden, wird die Variable [i] als Parameter an die Funktionen f1 und f2 übergeben;
- Zeilen 9, 19: Die Funktionen f1 und f2 geben die geänderte Variable [i] an das Hauptprogramm zurück. Das Hauptprogramm ruft sie in den Zeilen 36 und 37 ab;
Ergebnisse
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_02.py
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[1,30]
[i,j]=[2,0]
Process finished with exit code 0
6.3. Skript [fonc_03]: Geltungsbereich von Variablen
Das Skript [fonc_03] veranschaulicht eine Besonderheit von Variablen, die sowohl innerhalb einer Funktion als auch im aufrufenden Code verwendet werden, je nachdem, ob die Variable innerhalb der Funktion nur zum Lesen verwendet wird oder nicht.
Anmerkungen
- Zeile 34: Der Hauptcode definiert eine Variable [i];
- Zeilen 1–5: Die Funktion f1 verwendet ebenfalls eine Variable [i], ohne ihr einen Wert zuzuweisen. Hierbei handelt es sich um ein Auslesen der Variablen [i]. In diesem Fall wird die Variable [i] aus dem aufrufenden Code (Zeile 34) verwendet;
- Zeilen 8–18: Die Funktion f2 verwendet ebenfalls eine Variable [i], weist ihr jedoch in Zeile 16 einen Wert zu. Durch die Zuweisung eines Werts an die Variable [i] in f2 wird [i] automatisch zu einer lokalen Variablen der Funktion [f2]. Diese Funktion „verbirgt“ daher die Variable [i] vor dem aufrufenden Code;
- Zeile 14: Der Schreibvorgang auf die lokale Variable [i] schlägt fehl, da sie keinen Wert hat, wenn Zeile 14 erreicht wird. Sie erhält ihren Wert in Zeile 16. Es tritt eine Ausnahme auf. Aus diesem Grund wurde Zeile 14 in einen try/catch-Block gesetzt;
- Zeilen 21–29: Die Funktion f3 macht dasselbe wie die Funktion f2, definiert ihre lokale Variable [i] jedoch früher;
Ergebnisse
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_03.py
[f1] i=10
[f1] j=20
[main] i=10, j=20
[f2] erreur=local variable 'i' referenced before assignment
[main] i=10
[f3] i=7
[main] i=10
Process finished with exit code 0
6.4. Skript [fonc_04]: Modus der Parameterübergabe
Das Skript lautet wie folgt:
Ergebnisse
Anmerkungen:
- In Python ist alles ein Objekt. Manche Objekte werden als „unveränderlich“ bezeichnet: Sie können nicht verändert werden. Dies gilt für Zahlen, Zeichenketten und Tupel. Wenn Python-Objekte als Argumente an Funktionen übergeben werden, werden ihre Referenzen übergeben, es sei denn, diese Objekte sind „unveränderlich“; in diesem Fall wird der Wert des Objekts übergeben;
- Die Funktionen f1 (Zeile 2) und f2 (Zeile 7) sollen die Übergabe eines Ausgabeparameters veranschaulichen. Wir möchten, dass der tatsächliche Parameter einer Funktion durch die Funktion verändert wird;
- Zeilen 2–3: Die Funktion f1 verändert ihren formalen Parameter a. Wir wollen wissen, ob auch der tatsächliche Parameter verändert wird;
- Zeilen 14–15: Der tatsächliche Parameter ist x = 1. Zeile 2 der Ergebnisse zeigt, dass der tatsächliche Parameter nicht verändert wird. Somit sind der tatsächliche Parameter x und der formale Parameter a zwei verschiedene Objekte;
- Zeilen 8–10: Die Funktion f2 modifiziert ihre formalen Parameter a und b und gibt sie als Ergebnisse zurück;
- Zeilen 17–18: Die tatsächlichen Parameter (x, y) werden an f2 übergeben, und das Ergebnis von f2 wird (x, y) zugewiesen. Zeile 3 der Ergebnisse zeigt, dass die tatsächlichen Parameter (x, y) geändert wurden.
Wir schließen daraus, dass „unveränderliche“ Objekte, wenn sie Ausgabeparameter sind, Teil der von der Funktion zurückgegebenen Ergebnisse sein müssen.
6.5. Skript [fonc_05]: Reihenfolge der Funktionen in einem Skript
Das Skript [fonc_05] zeigt, dass eine Funktion nicht aufgerufen werden kann, wenn sie zuvor im Code noch nicht aufgetreten ist:
Anmerkungen
- Zeile 2 führt zu einem Fehler, da sie die Funktion f2 verwendet, die im Skript noch nicht definiert wurde;
Ergebnisse
6.6. Skript [fonc_06]: Reihenfolge der Funktionen in einem Skript
Das Skript [fonc_06] zeigt, dass das, was für den aufrufenden Code gilt, nicht für Funktionen gilt:
Anmerkungen
- Zeile 3: Die Funktion [f2] verwendet die später im Skript definierte Funktion [f1]. Dies führt jedoch nicht zu einem Fehler. Wir können daher schlussfolgern, dass die Reihenfolge, in der Funktionen in einem Python-Skript definiert werden, keine Rolle spielt;
Ergebnisse
6.7. Skript [fonc_07]: Verwendung von Modulen
Das Skript [fonc_07] zeigt, wie Funktionen in einem Modul isoliert werden.

Wir isolieren wiederverwendbare Funktionen in einem Modul, anstatt sie von einem Skript in ein anderes zu verschieben:
- legen wir sie in einer separaten Datei ab, die wir auf eine bestimmte Weise deklarieren;
- Skripte, die diese Funktionen benötigen, „importieren“ das Modul, das sie enthält;
Das Skript [fonctions_module_01] sieht wie folgt aus:
Es gibt mehrere Möglichkeiten, um sicherzustellen, dass die Funktionen im Skript [fonctions_module_01] von anderen Skripten aufgerufen werden können. Diese Methoden unterscheiden sich je nachdem, ob das Skript innerhalb von [PyCharm] ausgeführt wird oder nicht.
In [PyCharm] wird in bestimmten Ordnern, den sogenannten [Root Sources], nach importierten Modulen gesucht. Es gibt zwei Möglichkeiten, einen Ordner als [Root Source] festzulegen:

- in [4] hat der Ordner seine Farbe geändert;
Nach diesem Vorgang wird der Ordner [functions/modules] als Quellordner erkannt. Sie können dann in einem Skript schreiben:
Um die im Modul [functions_module_01.py] definierte Funktion f2 zu importieren/zu verwenden.
![]() |
Eine weitere Möglichkeit ist die Verwendung der Projekteigenschaften:
- Oben ermöglicht die Sequenz [1-6], den Ordner [shared] als Speicherort für zu importierende Module zu verwenden;
Vorerst werden wir keinen anderen Ordner als [Sources Root] als das Projektverzeichnis angeben:

Sobald dies erledigt ist, können wir das folgende Skript [fonc-07] schreiben:
- Zeile 2: Wir importieren das [sys]-Objekt, damit wir in Zeile 5 dessen [path]-Attribut verwenden können, das den sogenannten [Python Path] bereitstellt: eine Liste von Verzeichnissen, in denen nach importierten Modulen gesucht wird;
- Zeile 6: Wir importieren die Funktion f2 aus dem Modul [fonctions_module_01]. Um auf dieses Modul zu verweisen, verwenden wir den Pfad, der vom Projektstammverzeichnis zum Modul führt. Bei PyCharm ist das Projektstammverzeichnis immer in den Ordnern enthalten, die durchsucht werden, wenn in einem Skript nach einem importierten Modul gesucht wird. Dieser Ordner ist daher Teil des [Python Path] des Projekts. Dies können wir anhand von Zeile 5 überprüfen;
- Zeile 6: Würden wir den Pfad vom Projektstammverzeichnis zum Ordner [fonctions_module_01] beschreiben, würden wir [fonctions/shared/fonctions_module_01] schreiben. Im Pfad eines Moduls wird das / durch einen Punkt ersetzt. Wir schreiben daher [fonctions.modules.fonctions_module_01];
- Nach Zeile 6 wird die Funktion f2 definiert. Wir verwenden sie in Zeile 8;
Ergebnisse
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_07.py
Python path=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
310
Process finished with exit code 0
Oben:
- grün hervorgehoben, sehen wir, dass das Projektverzeichnis Teil des [Python Path] ist;
- gelb hervorgehoben ist, sehen wir, dass der Ordner, der das ausgeführte Skript enthält, ebenfalls Teil des [Python-Pfads] ist;
- die anderen Elemente des [Python-Pfads] stammen direkt aus dem Python-Installationsordner;
Was passiert, wenn wir [fonc-07] nicht mit PyCharm ausführen?


- In [1] führen wir das Skript [fonc-07] aus. Wir befinden uns im Ordner [functions];
- In [2] sehen wir, dass das Ausführungsverzeichnis Teil des [Python Path] ist. Dies ist immer der Fall. Wir sehen auch, dass das Stammverzeichnis [C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020] nicht Teil des [Python Path] ist;
- In [3] meldet der Python-Interpreter, dass er das Modul [fonctions] nicht finden kann;
Um das importierte Modul [fonctions.shared.fonctions_module_01] zu finden, durchsucht der Python-Interpreter die Ordner im [Python Path] nach einem Unterordner namens [fonctions]. Er kann ihn nirgendwo finden. Dies liegt daran, dass sich der Unterordner [fonctions] unter dem Ordner [C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020] befindet, der nicht Teil des [Python-Pfads] ist.
Das Skript [fonc-08] bietet eine mögliche Lösung für dieses Problem.
6.8. Skript [fonc_08]: Hinzufügen von Ordnern zum [Python Path]
Es ist möglich, den [Python-Pfad] programmgesteuert zu ändern, wie im Skript [fonc-08] gezeigt:
Anmerkungen
- Zeile 4: Die Spezialvariable [__file__] ist der Name des Skripts, das gerade ausgeführt wird. Je nach Ausführungskontext kann dieser Name absolut (PyCharm) oder relativ (Konsole) sein. Die Funktion [os.path.abspath] gibt den absoluten Pfad der Datei zurück, deren Name ihr übergeben wird. Die Funktion [os.path.dirname] gibt den absoluten Pfad des Verzeichnisses zurück, das die Datei enthält, deren Name ihr übergeben wird;
- Zeile 10: [sys.path] ist eine Liste, die die Namen der Verzeichnisse enthält, in denen gesucht wird, wenn ein Modul gesucht wird. Wir fügen das in Zeile 4 definierte Projektstammverzeichnis zu dieser Liste hinzu;
- Wir zeigen den [Python-Pfad] vor (Zeile 8) und nach (Zeile 12) der Änderung an;
- Zeile 15: Wir importieren das Modul [fonctions_module_01], das die Funktion f2 enthält;
Die Ausführung in PyCharm liefert folgende Ergebnisse:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_08.py
Python path avant=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
Python path après=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions/shared']
310
Process finished with exit code 0
- Zeile 3: Wir sehen, dass der Ordner [shared] zweimal im [Python Path] erscheint. Wir können dies vermeiden, aber es verursacht hier keine Probleme;
- Zeile 4: Die Funktion f2 wurde erfolgreich ausgeführt;
Führen wir nun [fonc-08] in einem Terminal aus:
(venv) C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\fonctions>python fonc_08.py
Python path avant=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
Python path après=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions/shared']
310
- Zeile 2: Wie zuvor befindet sich der Ordner [shared] nicht im [Python-Pfad];
- Zeile 3: Jetzt ist er es;
- Zeile 4: Die Funktion f2 wurde gefunden;
6.9. Skript [fonc_09]: Deklaration von Parametertypen
Das Skript [fonc_09] zeigt, dass Sie sowohl den Typ der Parameter einer Funktion als auch den des Ergebnisses deklarieren können. Diese Deklaration dient jedoch lediglich der Dokumentation der Funktion. Der Python-Interpreter prüft nicht, ob die tatsächlichen Funktionsparameter vom erwarteten Typ sind. PyCharm markiert jedoch Typinkonsistenzen zwischen tatsächlichen und formalen Parametern. Allein aus diesem Grund sind Typdeklarationen unverzichtbar.
Das Skript lautet wie folgt:
Anmerkungen:
- Zeile 5: Wir deklarieren, dass der formale Parameter [param] vom Typ [int] ist und dass der Rückgabetyp der Funktion ebenfalls [int] ist;
- Zeile 11: Der tatsächliche Parameter der Funktion [show] hat den richtigen Typ;
- Zeile 12: Der tatsächliche Parameter der Funktion [show] hat nicht den richtigen Typ;
Ergebnisse
- Zeile 10: Der Typ des Parameters [param] ist [str]. Wenn diese Meldung erscheint, haben wir bereits den Code der Funktion [show] eingegeben. Der Python-Interpreter hat daher akzeptiert, dass der tatsächliche Parameter der Funktion [show] vom Typ [str] ist;
- Zeile 7 des Codes löst die in den Zeilen 4–10 der Ergebnisse gezeigte Ausnahme aus;
PyCharm weist dennoch darauf hin, dass ein Problem vorliegt:

In [1] hat PyCharm den fehlerhaften Aufruf hervorgehoben.
6.10. Skript [fonc_10]: benannte Parameter
Um Parameter an eine Funktion zu übergeben, können Sie die Namen ihrer formalen Parameter verwenden. In diesem Fall müssen Sie die Reihenfolge der formalen Parameter nicht einhalten:
Anmerkungen
- Zeile 2: Die Funktion f hat zwei formale Parameter, x und y;
- Zeile 7: Beim Aufruf der Funktion f können Sie die Namen der formalen Parameter verwenden. Diese Vorgehensweise kann in mindestens zwei Fällen nützlich sein:
- Die Funktion hat viele Parameter, von denen die meisten Standardwerte haben. Beim Aufruf der Funktion ermöglicht die oben beschriebene Technik, nur jene Parameter zu initialisieren, für die Sie den Standardwert nicht verwenden möchten;
- Wenn die formalen Parameter aussagekräftige Namen haben, verbessert die Verwendung benannter Parameter im Funktionsaufruf die Lesbarkeit des Codes;
Ergebnisse
6.11. Skript [fonc_11]: rekursive Funktion
Das Skript [fonc_11] ist ein Beispiel für eine rekursive Funktion (die sich selbst aufruft):
Kommentare
- Zeilen 1–9: die Fakultätsfunktion;
- Zeile 9: Die [Fakultäts-]Funktion ruft sich selbst auf;
- Zeilen 5–6: Eine rekursive Funktion muss immer aufhören, wenn eine Bedingung erfüllt ist; andernfalls kommt es zu einer unendlichen Rekursion;
Ergebnisse
6.12. Skript [fonc_12]: rekursive Funktion
Die Funktion [fonc_12] liefert weitere Details zur Funktionsweise der Rekursion:
Kommentare
- Zeile 5: Wir konzentrieren uns weiterhin auf die Fakultätsfunktion. Wir fügen ihr den Parameter [j] hinzu;
- Zeile 12: Die Variable j wird bei jeder Fakultätsberechnung regelmäßig erhöht. Wir zeigen ihren Wert vor (Zeile 12) und nach (Zeile 16) der Rekursion (Zeile 15) an;
Ergebnisse
- Zeilen 2–8: Wir sehen, dass der Wert von [j] so lange ansteigt, wie die Rekursion andauert, bis die Bedingung erfüllt ist, bei der die Rekursion beendet wird. Ab diesem Zeitpunkt erfolgt die Rückgabe aus den Aufrufen der Funktion [fact] in umgekehrter Reihenfolge der Aufrufe;
- Zeilen 10–16: Diese Anzeigen spiegeln die aufeinanderfolgenden Rückgaben aus dem Aufruf von factorial wider. Die Variable [j] kehrt zu ihrem Ausgangswert 1 zurück;
