Unterscheidung zwischen Klassen- und Instanzvariablen erklärt.
Variablen sind im Wesentlichen Symbole, die für einen Wert stehen, den wir in einem Programm verwenden. Bei der objektorientierten Programmierung können Variablen auf der Klassen- oder Instanzebene verwendet werden. Ziel dieses Artikels ist es, eine klare Unterscheidung zwischen den Variablentypen zu treffen, die das Objektmodell von Python bietet, und ein besonderes Verhalten zu erörtern, das zu einigen überraschenden Ergebnissen führen kann, wenn es nicht beachtet wird.
Im Objektmodell von Python gibt es zwei Arten von Datenattributen für Python-Objekte: Klassenvariablen und Instanzvariablen.
Klassenvariablen – werden innerhalb der Klassendefinition deklariert (aber außerhalb der Instanzmethoden). Sie sind nicht an ein bestimmtes Objekt der Klasse gebunden und werden daher von allen Objekten der Klasse gemeinsam genutzt. Die Änderung einer Klassenvariable wirkt sich auf alle Instanzobjekte gleichzeitig aus.
Instanzvariable – Wird innerhalb der Konstruktormethode der Klasse deklariert (die __init__
Methode). Sie sind an die jeweilige Objektinstanz der Klasse gebunden, daher ist der Inhalt einer Instanzvariablen völlig unabhängig von einer Objektinstanz zur anderen.
Beginnen wir mit einem kurzen und einfach zu verdauenden Beispiel:
class Car:
wheels = 4 # <- Class variable def __init__(self, name):
self.name = name # <- Instance variable
Oben ist die einfache, schnörkellose Car-Klasse definiert. Jede Instanz der Klasse hat die Klassenvariable wheels zusammen mit dem Namen der Instanzvariable. Lassen Sie uns die Klasse instanziieren, um auf die Variablen zuzugreifen.
>>> jag = Car('jaguar')
>>> fer = Car('ferrari')>>> jag.name, fer.name
('jaguar', 'ferrari')>>> jag.wheels, fer.wheels
(4, 4)>>> Car.wheels
4
Der Zugriff auf den Namen der Instanzvariablen ist ziemlich einfach. Beim Zugriff auf die Klassenvariable gibt es jedoch etwas mehr Flexibilität. Wie oben können wir über die Objektinstanz oder die Klasse selbst auf Räder zugreifen.
Auch der Versuch, über die Klasse auf den Namen zuzugreifen, führt zu einem AttributeError, da Instanzvariablen objektspezifisch sind und beim __init__
Konstruktoraufruf erstellt werden. Das ist der zentrale Unterschied zwischen Klassen- und Instanzvariablen.
>>> Car.name
AttributeError: type object 'Car' has no attribute 'name'
Nun nehmen wir einmal an, dass unser Jaguar 3 Räder hat. (ja, das ist blöd, aber sei nachsichtig damit!!! 😅). Um das in unserem Code darzustellen, können wir die Variable wheels ändern.
>>> Car.wheels = 3
Was wir oben getan haben, wird alle Autos mit 3 Rädern machen, da wir eine Klassenvariable geändert haben, die für alle Instanzen der Klasse Car gilt.
>>> jag.wheels, fer.wheels
(3, 3)
Die Änderung einer Klassenvariable im Klassennamensraum wirkt sich also auf alle Instanzen der Klasse aus. Machen wir die Änderung rückgängig und ändern wir die wheels-Variable mit dem jag-Objekt.
>>> Car.wheels = 4
>>> jag.wheels = 3
So erhalten wir die gewünschte Ausgabe.
>>> jag.wheels, fer.wheels, Car.wheels
(3, 4, 4)
Wir haben zwar das gewünschte Ergebnis erhalten, aber was hinter den Kulissen passiert ist, ist eine neue wheels-Variable, die dem jag-Objekt hinzugefügt wurde, und diese neue Variable überschattet die Klassenvariable mit demselben Namen, überschreibt sie und versteckt sie. Wir können auf beide Variablen wie folgt zugreifen:
>>> jag.wheels, jag.__class__.wheels
(3, 4)
Daraus können wir schließen, dass jag.wheels = 3
eine neue Instanzvariable mit demselben Namen wie die Klassenvariable (wheels) erstellt hat. Dies ist ein wichtiges Konzept, dessen man sich bewusst sein sollte.
Die Verwendung von klassen- und instanzspezifischen Variablen kann sicherstellen, dass unser Code das DRY-Prinzip einhält, um Wiederholungen im Code zu reduzieren.
Dies zu wissen, kann meiner Meinung nach sehr nützlich sein und einem viele Stunden der Fehlersuche ersparen. 😇
Lesen Sie in diesem Beitrag weiter über die verschiedenen Arten von Methoden (Instanz, Klasse & statisch) in Python.
Schlussfolgerungen
- Klassenvariablen werden von allen Objekten gemeinsam genutzt, während Instanzvariablen für Daten bestimmt sind, die für jede Instanz einzigartig sind.
- Instanzvariablen überschreiben die Klassenvariablen mit demselben Namen, was versehentlich Fehler oder überraschendes Verhalten in unserem Code hervorrufen kann.