Home | Lehre | Videos | Texte | Vorträge | Software | Person | Impressum, Datenschutzerklärung | ![]()
Stand: 2025-04-02
weitgehend formuliert von ChatGPT 4, verbessert von ChatGPT 4o,
redigiert/korrigiert von Jörn Loviscach
In Python gibt es globale und lokale Variablen. Die Konzepte gleichen denen von C, aber auch hier gibt es wieder einige wichtige Unterschiede.
Lokale Variablen werden innerhalb einer Funktion definiert und sind nur innerhalb dieser Funktion sichtbar. Von außerhalb der Funktion kann nicht auf sie zugegriffen werden. Beispiel:
def meine_funktion():
x = 10 # Lokale Variable
print(x)
meine_funktion() # Ausgabe: 10
print(x) # Fehler: NameError: name 'x' is not definedGlobale Variablen werden außerhalb von Funktionen definiert und sind von überall im Programm aus zugänglich, auch innerhalb von Funktionen. Beispiel:
y = 20 # Globale Variable
def meine_funktion():
print(y)
meine_funktion() # Ausgabe: 20
print(y) # Ausgabe: 20Wenn man innerhalb einer Funktion einer globalen Variable etwas
zuweisen will, ist das Schlüsselwort global nötig.
Andernfalls erstellt Python eine neue lokale Variable mit demselben
Namen. Beispiel:
z = 30 # Globale Variable
def meine_funktion():
global z
z = 40 # Ändert den Wert der globalen Variable
meine_funktion()
print(z) # Ausgabe: 40Ein Unterschied von Python zu vielen C-Varianten besteht darin, dass
Variablen, die in einer Schleife (z. B. einer for-Schleife)
angelegt werden, in Python nicht lokal auf den Schleifenblock
beschränkt sind. Sie existieren auch noch nach der Schleife
weiter:
# vorher kein i oder a definiert
for i in range(3):
a = 7
print(i, a) # Ausgabe: 2 7Die Variablen i und a bleiben nach der
Schleife erhalten. Das kann nützlich, aber auch unerwartet sein.
Es ist im Allgemeinen eine gute Praxis, die Verwendung von globalen Variablen zu minimieren und stattdessen Parameter und Rückgabewerte zu verwenden, um Daten zwischen Funktionen auszutauschen. Dies verbessert die Lesbarkeit, Wartbarkeit und Testbarkeit des Codes.
In Python sind Listen ein fundamentaler Datentyp, der verwendet wird, um mehrere Elemente in einer geordneten Reihenfolge zu speichern. Listen in Python ähneln Arrays in C, bieten jedoch mehr Flexibilität und eingebaute Funktionalitäten.
Im Gegensatz zu Arrays in C müssen Listen in Python nicht mit einer festen Größe initialisiert werden. Sie können zur Laufzeit wachsen oder schrumpfen, indem Elemente hinzugefügt oder entfernt werden. Außerdem können Listen Elemente unterschiedlicher Datentypen enthalten, während Arrays in C meist nur Elemente desselben Datentyps speichern.
Eine Liste in Python wird mit eckigen Klammern []
deklariert und kann Elemente verschiedener Datentypen enthalten. Hier
ist ein Beispiel:
my_list = [1, 2, 'drei', 4.0, True]Auf die Elemente einer Liste kann über ihren Index zugegriffen werden, wobei der Index bei 0 beginnt:
print(my_list[0]) # Ausgabe: 1
print(my_list[2]) # Ausgabe: 'drei'forIn Python gibt es verschiedene Möglichkeiten, über Listen zu
iterieren. Eine davon ist die Verwendung der schon bekannten
for-Schleife mit einer Liste statt mit range.
Hier ist ein einfaches Beispiel:
zahlen = [1, 2, 3, 4, 5]
for zahl in zahlen:
print(zahl)Ausgabe:
1
2
3
4
5
Listen in Python bieten eine Vielzahl von nützlichen Methoden:
append(element): Fügt ein Element am Ende der Liste
hinzu.insert(index, element): Fügt ein Element an der
angegebenen Position ein.remove(element): Entfernt das erste Vorkommen eines
Elements aus der Liste.pop(): Entfernt das letzte Element und gibt es
zurück.pop(index): Entfernt und gibt das Element an der
angegebenen Position zurück.sort(): Sortiert die Elemente der Liste in
aufsteigender Reihenfolge.reverse(): Kehrt die Reihenfolge der Elemente in der
Liste um.
Die Anzahl an Elementen einer Liste zahlen erhält man mit
len(zahlen), die Summe der Elemente mit
sum(zahlen). Diese beiden sind keine Methoden wie das schon
genannte append, sondern Funktionen; hier steht also nicht
zahlen.tu_etwas(), sondern tu_etwas(zahlen).
(Später im Semester mehr dazu.)
Listen lassen sich mit dem +-Operator addieren, um eine
neue Liste zu erhalten, die die Elemente beider Listen enthält.
Beispiel:
liste1 = [1, 2, 3]
liste2 = [4, 5, 6]
liste3 = liste1 + liste2
print(liste3) # Ausgabe: [1, 2, 3, 4, 5, 6]Listen lassen sich auch mit dem *-Operator
multiplizieren, um eine neue Liste zu erhalten, die die Elemente der
ursprünglichen Liste mehrfach enthält. Beispiel:
liste = [1, 2, 3]
liste_mehrfach = liste * 3
print(liste_mehrfach) # Ausgabe: [1, 2, 3, 1, 2, 3, 1, 2, 3]Sowohl die Addition als auch die Multiplikation von Listen lassen die ursprünglichen Listen unverändert; sie erzeugen neue Listen derselben Elemente.
Python unterstützt auch negative Indizes, um auf Elemente vom Ende der Liste aus zuzugreifen. Der Index -1 bezieht sich auf das letzte Element, -2 auf das vorletzte Element usw.
my_list = [1, 2, 3, 4, 5]
print(my_list[-1]) # Ausgabe: 5
print(my_list[-3]) # Ausgabe: 3Slices ermöglichen es, Teilbereiche einer Liste zu extrahieren. Die
Syntax lautet list[start:end:step], wobei
start der Startindex, end der Endindex (Index,
vor dem abgebrochen wird) und step die
Schrittweite ist.
my_list = [1, 2, 3, 4, 5]
print(my_list[1:4]) # Ausgabe: [2, 3, 4]
print(my_list[::2]) # Ausgabe: [1, 3, 5]
print(my_list[1:-1]) # Ausgabe: [2, 3, 4]
print(my_list[::-1]) # Ausgabe: [5, 4, 3, 2, 1]my_list[1:4] gibt eine neue Liste mit den Elementen von
Index 1 bis 3 zurück.my_list[::2] gibt eine neue Liste mit jedem zweiten
Element zurück.my_list[1:-1] gibt eine neue Liste mit den Elementen
von Index 1 bis zum vorletzten Element zurück.my_list[::-1] gibt eine neue Liste mit den Elementen in
umgekehrter Reihenfolge zurück.Listen können als Parameter an Funktionen übergeben werden. In Python werden Listen (wie auch alles andere; später mehr dazu) als Referenz übergeben, also ähnlich wie man in C mit Pointern arbeitet. Das bedeutet, dass Änderungen an der Liste innerhalb der Funktion auch außerhalb der Funktion sichtbar sind.
Hier ist ein Beispiel für eine Funktion, die eine Liste als Parameter erhält und ein Element hinzufügt:
def add_item(my_list: list, item: any) -> None:
my_list.append(item)In diesem Beispiel verwenden wir Type Hints, um anzuzeigen, dass
my_list eine Liste und item ein beliebiger
Datentyp sein kann. Die Funktion hat formal keinen Rückgabewert, gibt
also None zurück.
Type Hints können verwendet werden, um den Typ von Listenelementen anzugeben. Hier ist ein Beispiel:
def beispiel_funktion(namen: list[str]) -> None:
for name in namen:
print(name)Seit Version 3.10 kennt Python das Statement match. Es
ist eine elegante Alternative zum switch-Statement in C.
Mit match lassen sich verschiedene Fälle (Cases) basierend
auf dem Wert eines Ausdrucks unterscheiden und der entsprechende Code
ausführen.
In C ist switch auf Integer-Werte und Konstanten
beschränkt, während match in Python mit verschiedenen
Datentypen und komplexen Mustern arbeiten kann. Die
case-Klauseln in Python benötigen kein explizites
break, um ein Durchfallen
zu verhindern. Jeder
case wird getrennt behandelt.
Python erlaubt die Verwendung eines Wildcard
-Falls
(case _), der ausgeführt wird, wenn kein anderes Muster
zutrifft. In C gibt es dafür das optionale default.
Hier ist ein einfaches Beispiel für die Verwendung von
match in Python:
def describe_color(color):
match color:
case 'red':
return 'Rot wie eine Tomate'
case 'green':
return 'Grün wie Gras'
case 'blue':
return 'Blau wie der Himmel'
case _:
return 'Unbekannte Farbe'
print(describe_color('red')) # Ausgabe: Rot wie eine Tomate
print(describe_color('purple')) # Ausgabe: Unbekannte FarbeIn diesem Beispiel wird der Wert von color mit den
verschiedenen Mustern verglichen und der entsprechende String
zurückgegeben.
Hier ein komplizierteres Beispiel; beachte, dass anders als in C kein
break verwendet wird:
def calculate_price(product, quantity, discount):
match product:
case 'apple' if quantity > 10:
price = 0.5 * quantity
case 'apple':
price = 0.8 * quantity
case 'banana' if discount:
price = 0.6 * quantity
case 'banana':
price = 1.0 * quantity
case _:
price = 0
return price
# Beispielaufrufe
print(calculate_price('apple', 5, False)) # Ausgabe: 4.0
print(calculate_price('apple', 15, False)) # Ausgabe: 7.5
print(calculate_price('banana', 3, True)) # Ausgabe: 1.8
print(calculate_price('banana', 3, False)) # Ausgabe: 3.0
print(calculate_price('orange', 5, False)) # Ausgabe: 0In diesem Beispiel haben wir eine Funktion
calculate_price, die den Preis basierend auf dem Produkt,
der Menge und einem optionalen Rabatt berechnet. Wir verwenden das
match-Statement, um verschiedene Fälle abzudecken:
appleist und die Menge größer als 10 ist, wird ein Sonderpreis von 0,5 pro Stück berechnet.
appleist, aber die Menge nicht größer als 10 ist, wird der reguläre Preis von 0,8 pro Stück berechnet.
bananaist und ein Rabatt gewährt wird, wird ein ermäßigter Preis von 0,6 pro Stück berechnet.
bananaist, aber kein Rabatt gewährt wird, wird der reguläre Preis von 1,0 pro Stück berechnet.
Die Verwendung von if-Bedingungen innerhalb der
case-Klauseln ermöglicht es uns, zusätzliche Bedingungen zu
überprüfen, bevor ein bestimmter Fall ausgeführt wird. Soll ein
case mehrere Werte abdecken, kann man diese mit
| zusammenfassen: case 23 | 42 In diesem Fall
bedeutet der vertikale Strich nicht das bitweise Oder.
Python bietet mit dem enum-Modul eine Möglichkeit,
symbolische Namen für Konstanten zu definieren, ähnlich wie das
enum in C. Enums in Python sind jedoch mächtiger und bieten
zusätzliche Funktionalitäten.
Ein Enum in Python wird durch Ableiten von der Klasse
Enum definiert. (Klassen und Ableitungen kommen später noch
ausführlich.) Hier ist ein Beispiel:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3In diesem Beispiel wird ein Enum namens Color definiert,
das drei Konstanten (RED, GREEN und
BLUE) enthält. Jeder Konstante wird ein eindeutiger Wert
zugewiesen.
Auf die Konstanten eines Enums kann über den Enum-Namen und den Konstantennamen zugegriffen werden:
print(Color.RED) # Output: Color.RED
print(Color.RED.value) # Output: 1Mit Enums kann match verwendet werden, um basierend auf
dem Wert einer Enum-Konstante verschiedene Aktionen auszuführen:
def print_color(color):
match color:
case Color.RED:
print('The color is red')
case Color.GREEN:
print('The color is green')
case Color.BLUE:
print('The color is blue')
print_color(Color.RED) # Output: The color is redDas Lesen und Schreiben von Textdateien ist eine alltägliche Operation. Auch hier erinnert Python wieder an C, mit mehr Komfort.
Um eine Datei in Python zu öffnen, verwendet man die Funktion
open(). Sie erwartet als Parameter den Dateinamen und
optional den Modus, in dem die Datei geöffnet werden soll (z.B. r
für Lesen, w
für Schreiben).
file = open('datei.txt', 'r')
Gibt man hier nur den Namen der Datei an, muss sie typischerweise direkt
neben der Python-Datei liegen. Es sind aber auch absolute und relative
Pfadangaben möglich. Vorsicht damit unter Windows: Dies benutzt den
Rückwärtsstrich \ als Trenner, der aber in Zeichenketten
Sonderbedeutungen wie \n = neue Zeile und \t =
Tabulator besitzt. Eine Zeichenkette wie
'C:\irgendwo\test.txt' wird deshalb nicht akzeptiert.
Stattdessen kann man wie in C schreiben:
'C:\\irgendwo\\test.txt' oder Python-typisch ein
r davorsetzen, um die Sonderbedeutungen des \
abzuschalten: r'C:\irgendwo\test.txt'. Aber siehe auch das
Thema Pathlib
weiter unten.
Nach dem Öffnen der Datei sollte sie auch wieder geschlossen werden,
um Ressourcen freizugeben und anderen Programmen bzw. Usern wieder den
Zugriff auf die Datei zu gestatten. Dies geschieht mit der Methode
close().
file.close()Zum Lesen von Daten aus einer Datei stehen verschiedene Methoden zur Verfügung:
read(): Liest den gesamten Inhalt der Datei als
String.readline(): Liest eine einzelne Zeile als String aus
der Datei.readlines(): Liest alle Zeilen der Datei in eine Liste
von Strings.Beispiel:
file = open('datei.txt', 'r')
content = file.read()
print(content)
file.close()Zum Schreiben von Daten in eine Datei verwendet man die Methode
write(). Sie erwartet einen String als Parameter, der in
die Datei geschrieben wird.
Beispiel:
file = open('datei.txt', 'w')
file.write('Hallo, Welt!')
file.close()Um die Datei nicht zu überschreiben, sondern weiteren Text an sie
anzuhängen, öffnet man sie im Modus 'a' (für append
)
statt 'w'.
with-StatementUm sicherzustellen, dass eine Datei immer ordnungsgemäß geschlossen
wird, auch im Falle einer Exception (mehr dazu später im Semester),
bietet Python das with-Statement. Es sorgt automatisch für
das Schließen der Datei, sobald der with-Block verlassen
wird.
Beispiel:
with open('datei.txt', 'r') as file:
content = file.read()
print(content)Innerhalb des with-Blocks kann die Datei wie gewohnt
verwendet werden. Nach Verlassen des Blocks wird die Datei automatisch
geschlossen, ohne dass explizit close() aufgerufen werden
muss.
Von C ist man gewohnt, dass Textdateien in ASCII oder (als Erweiterung von ASCII) einer systemabhängigen Codepage gespeichert werden. In Python ist das anders: Hier wird für Textdateien standardmäßig die Kodierung UTF-8 verwendet; unter Windows kann allerdings noch etwas anderes eingestellt sein.
UTF-8 ist eine Kodierung für Unicode-Zeichen. Es kann damit eine große Anzahl an Zeichen aus verschiedenen Sprachen dargestellt werden, darunter auch Sonderzeichen und Emojis. UTF-8 ist abwärtskompatibel zu ASCII: Die ersten 128 Zeichen entsprechen dem ASCII-Zeichensatz.
Alte Textdateien und alte Programme können noch andere Codierungen als UTF-8 verwenden, was man daran erkennt, dass Zeichen wie ä, € und erst recht 🔋 nicht korrekt übertragen werden. Dann ist es nötig, in Python die Codierung ausdrücklich anzugeben, wie in diesem Beispiel:
file = open('datei.txt', 'r', encoding='cp1252')'r' steht für read(lesen).
encoding gibt die Codierung der
Datei an. Für die Standard-Windows-Codepage verwendet man
'cp1252'. Umgekehrt könnte je nach Installation unter
Windows an dieser Stelle immer noch 'utf8' nötig sein, um
die üblichen UTF-8-codierten Textdateien zu verarbeiten.Die Handhabung von Dateipfaden (also den Angaben, welche Datei in
welchem wie verschachtelten Verzeichnis zu nutzen ist) kann schnell
komplex und fehleranfällig werden, besonders wenn es um
plattformübergreifende Entwicklung geht. Hier kommt pathlib
ins Spiel:
pathlib ebnet
die Unterschiede der verschiedenen Betriebssysteme beim Angaben von
Dateipfaden, zum Beispiel, dass Windows den Rückwärts-Schrägstrich
\ und Linux den normalen Schrägstrich /
benutzt, um ein Verzeichnis anzugeben.pathlib
lassen sich Pfade mühelos konstruieren, zerlegen und manipulieren.pathlib arbeitet nahtlos mit anderen Modulen wie
os und shutil zusammen.Dateien öffnen
from pathlib import Path
# Pfad erstellen
pfad = Path('ordner/datei.txt')
# Überprüfen, ob die Datei existiert
if pfad.exists():
# Datei öffnen und lesen
with open(pfad, 'r') as datei:
inhalt = datei.read()
print(inhalt)
else:
print('Die Datei existiert nicht.')Pfade erstellen und zusammensetzen:
# Pfad zum Home-Verzeichnis des Benutzers
home = Path.home()
# Pfad zu einer Datei im Downloads-Ordner
# Der Operator / bedeutet hier das Aneinanderhängen, egal welches Betriebssystem
file_path = home / 'Downloads' / 'example.txt'Dateien und Verzeichnisse überprüfen:
file_path = Path('path/to/file.txt')
if file_path.is_file():
print('Es ist eine Datei.')
elif file_path.is_dir():
print('Es ist ein Verzeichnis.')Durch Verzeichnisse iterieren:
directory = Path('path/to/directory')
for file in directory.iterdir():
if file.is_file() and file.suffix == '.txt':
print(file.name)