HOWTO · Python
Optionale Argumente für einen Klassenkonstruktor in Python
Erfahren Sie, wie Sie optionale Argumente für einen Klassenkonstruktor in Python festlegen
Auf dieser Seite
Ein Konstruktor kann einen Parameter optional machen, indem ihm in __init__ ein Standardwert zugewiesen wird. Lässt ein Aufrufer diesen Parameter weg, verwendet Python den Standardwert. Übergibt der Aufrufer einen Wert, verwendet Python stattdessen diesen. Parameter ohne Standardwert bleiben erforderlich. So kann eine Klasse eine sinnvolle gemeinsame Konfiguration bereitstellen und Aufrufern zugleich ermöglichen, eine Instanz anzupassen.
Standardargumente in Python verstehen
Ein Standardwert gehört zu einem Parameter in der Funktionsdefinition. Bei einem Aufruf werden Positionsargumente von links nach rechts zugeordnet, Schlüsselwortargumente dagegen anhand des Parameternamens. Ein Parameter mit Standardwert kann daher weiterhin ausdrücklich übergeben werden, entweder als Positions- oder als Schlüsselwortargument. „Optional“ bedeutet, dass der Aufrufer den Wert weglassen darf; es bedeutet nicht, dass der Parameter ausschließlich anhand seines Namens zugeordnet wird.
Optionale Argumente für einen Klassenkonstruktor in Python festlegen
Lege den Standardwert bei einem Konstruktor direkt in der Signatur von __init__ fest. Die folgende Klasse Point erfordert x und y und verwendet für z den Wert 0, wenn der Aufrufer ihn weglässt. Beim zweiten Aufruf wird ein anderer Wert für z übergeben, der den Standardwert überschreibt.
Führe dieses Beispiel aus. Der Code und die angezeigten Ausgaben bleiben unverändert auf Englisch:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
class Point:
def __init__(self, x, y, z=0):
self.x = x
self.y = y
self.z = z
def __str__(self):
return f"Point(x={self.x}, y={self.y}, z={self.z})"
print(Point(1, 2))
print(Point(54, 92, 7))
Point(x=1, y=2, z=0)
Point(x=54, y=92, z=7)
Die erste Instanz erhält z=0, die zweite speichert 7. Jede Instanz hat ihre eigenen Attribute; der Standardwert wirkt sich nur auf den Aufruf aus, bei dem z weggelassen wird.
Mehrere optionale Argumente in einem Klassenkonstruktor verwenden
Ein Konstruktor kann mehrere Standardwerte haben. Führe zuerst die erforderlichen Parameter auf und weise dann den Parametern, die Aufrufer weglassen dürfen, Standardwerte zu. Ein Rechteck kann zum Beispiel Maße erfordern und zugleich standardmäßig eine Füllfarbe und eine Umrandung erhalten. Der Code und die angezeigten Ausgaben bleiben unverändert auf Englisch:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
class Rectangle:
def __init__(self, width, height, color="white", outlined=False):
self.width = width
self.height = height
self.color = color
self.outlined = outlined
def describe(self):
return f"{self.width}x{self.height}, color={self.color}, outlined={self.outlined}"
print(Rectangle(10, 5).describe())
print(Rectangle(8, 8, color="blue", outlined=True).describe())
10x5, color=white, outlined=False
8x8, color=blue, outlined=True
Beim ersten Aufruf werden beide Standardwerte verwendet. Beim zweiten überschreiben die Schlüsselwortargumente sie unabhängig voneinander. Schlüsselwortargumente sind bei Konstruktoren mit mehreren optionalen Parametern hilfreich: Sie machen jeden gewählten Wert deutlich und erlauben es, einen weiteren Parameter mit Standardwert wegzulassen, ohne dessen Position ausfüllen zu müssen.
Reihenfolge der Parameter beachten
In einer gewöhnlichen Python-Funktionssignatur müssen Parameter mit Standardwerten auf Parameter ohne Standardwerte folgen. Ein gültiges Muster ist def __init__(self, required, option="default"):. Steht ein erforderlicher Parameter nach einem Parameter mit Standardwert, wie in def __init__(self, option="default", required):, ist das ein Syntaxfehler; Python kann diese Funktion daher nicht definieren. Ordne die Parameter so um, dass erforderliche Werte zuerst stehen, oder gib dem späteren Parameter einen passenden Standardwert, wenn er tatsächlich weggelassen werden darf.
Sobald die Signatur gültig ist, können Aufrufer weiterhin Positions- oder Schlüsselwortargumente verwenden. Zum Beispiel gibt Rectangle(8, 8, color="blue") die Farbe ausdrücklich an und verwendet für outlined den Standardwert. Vermeide Positionsargumente nach einem Schlüsselwortargument in einem Aufruf; verwende für die übrigen optionalen Einstellungen Schlüsselwortargumente.
Stolperfallen bei veränderlichen Standardwerten vermeiden
Standardwerte werden einmal ausgewertet, wenn Python die Funktion erstellt, und nicht bei jedem Aufruf erneut. Ein veränderlicher Standardwert wie eine Liste kann daher von mehreren Instanzen oder Aufrufen gemeinsam verwendet werden, wenn das Argument weggelassen wird. Verwende für Konstruktorparameter, die Sammlungen pro Instanz enthalten sollen, stattdessen None als Platzhalter und erstelle in __init__ eine neue Liste.
Dieses Beispiel vergleicht eine Funktion mit gemeinsam genutztem Listen-Standardwert mit dem sicheren Muster. Der letzte Aufruf zeigt außerdem, wie sich bewusst eine Liste übergeben lässt, die dem Aufrufer gehört. Der Code und die angezeigten Ausgaben bleiben unverändert auf Englisch.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
def collect(item, items=[]):
items.append(item)
return items
def collect_safely(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(collect("apple"))
print(collect("banana"))
print(collect_safely("apple"))
print(collect_safely("banana"))
print(collect_safely("pear", []))
['apple']
['apple', 'banana']
['apple']
['banana']
['pear']
Die erste Funktion behält dieselbe Liste bei, deshalb enthält ihr zweites Ergebnis beide Elemente. Die sichere Funktion erstellt bei jedem Aufruf, bei dem das Argument weggelassen wird, eine neue Liste; eine übergebene Liste wird unverändert verwendet. Wende dasselbe Muster „erst None, dann erstellen“ auf veränderliche Standardwerte in Konstruktoren an, zum Beispiel auf Listen und Dictionaries. Unveränderliche Standardwerte wie Zahlen, Zeichenketten und Tupel haben dieses Problem gemeinsam genutzter Änderungen nicht.