A Byte of Python

Klassen- und Objektvariablen

Wir haben bereits den Teil der Klassen und Objekte besprochen, der für ihre Funktionalität sorgt; nun werden wir den Teil betrachten, der die Daten enthält. Eigentlich handelt es sich um nichts anderes als gewöhnliche Variablen, die an die Namensräume der Klassen und Objekte gebunden sind, d.h. die Namen sind nur innerhalb des Kontextes der Klassen und Objekte gültig.

Es gibt zwei Arten von Feldern - Klassenvariablen und Objektvariablen, die danach klassifiziert werden, ob die Klasse oder das Objekt die jeweiligen Variablen besitzt.

Klassenvariablen werden gemeinsam benutzt, in dem Sinne, dass auf sie von allen Objekten (Instanzen) der Klasse zugegriffen wird. Es gibt nur eine Kopie einer Klassenvariable, und wenn irgendein Objekt eine Änderung an einer Klassenvariable vornimmt, dann spiegelt sich diese Änderung sofort auch in allen anderen Instanzen der Klasse wieder.

Objektvariablen gehören den einzelnen Objekten (Instanzen) der Klasse individuell. In diesem Fall hat jedes Objekt seine eigene Kopie des Feldes, d.h. sie werden nicht gemeinsam benutzt und sind auf keine Weise mit dem Feld des gleichen Namens in einer anderen Instanz der selben Klasse verknüpft. An einem Beispiel werden wir das leicht verstehen.

Benutzung von Klassen- und Objektvariablen

Beispiel 11.4. Benutzung von Klassen- und Objektvariablen (objvar.py)

				
#!/usr/bin/python

class Person:
	'''Stellt eine Person dar.'''
	bevoelkerung = 0

	def __init__(self, name):
		'''Initialisiert die Daten der Person.'''
		self.name = name
		print '(Initialisiere %s)' % self.name

		# Wenn diese Person erzeugt wird,
		# traegt er/sie zur Bevoelkerung bei
		Person.bevoelkerung += 1

	def __del__(self):
		'''Ich sterbe.'''
		print '%s verabschiedet sich.' % self.name

		Person.bevoelkerung -= 1

		if Person.bevoelkerung == 0:
			print 'Ich bin der letzte.'
		else:
			print 'Es gibt noch %d Leute.' % Person.bevoelkerung

	def sagHallo(self):
		'''Begruessung durch die Person.

		Das ist wirklich alles, was hier geschieht.'''
		print 'Hallo, mein Name ist %s.' % self.name

	def wieViele(self):
		'''Gibt die aktuelle Bevoelkerungszahl aus.'''
		if Person.bevoelkerung == 1:
			print 'Ich bin ganz allein hier.'
		else:
			print 'Es gibt hier %d Leute.' % Person.bevoelkerung

swaroop = Person('Swaroop')
swaroop.sagHallo()
swaroop.wieViele()

kalam = Person('Abdul Kalam')
kalam.sagHallo()
kalam.wieViele()

swaroop.sagHallo()
swaroop.wieViele()
				
				

Ausgabe

				
$ python objvar.py
(Initialisiere Swaroop)
Hallo, mein Name ist Swaroop.
Ich bin ganz allein hier.
(Initialisiere Abdul Kalam)
Hallo, mein Name ist Abdul Kalam.
Es gibt hier 2 Leute.
Hallo, mein Name ist Swaroop.
Es gibt hier 2 Leute.
Abdul Kalam verabschiedet sich.
Es gibt noch 1 Leute.
Swaroop verabschiedet sich.
Ich bin der letzte.
				
				

So funktioniert es

Dies ist ein langes Beispiel, aber es hilft uns, das Wesen von Klassen- und Objektvariablen zu demonstrieren. Die Variable bevoelkerung gehört hier zur Klasse Person und ist daher eine Klassenvariable. Die Variable name gehört dagegen zum jeweiligen Objekt (das durch self zugewiesen wird) und ist daher eine Objektvariable.

Wir nehmen daher auf die Klassenvariable bevoelkerung Bezug, indem wir schreiben Person.bevoelkerung und nicht self.bevoelkerung. Beachten Sie, dass eine Objektvariable mit dem gleichen Namen wie eine Klassenvariable diese Klassenvariable versteckt! Wir nehmen auf die Objektvariable name Bezug, indem wir die Schreibweise self.name in den Methoden dieses Objekts benutzen. Merken Sie sich diesen einfachen Unterschied zwischen Klassen- und Objektvariablen.

Beachten Sie, dass die __init__-Methode benutzt wird, um die Instanz von Person mit einem Namen zu initialisieren. In dieser Methode erhöhen wir den Zähler bevoelkerung um 1, weil wir eine weitere Person hinzugefügt haben. Beachten Sie auch, dass der Wert von self.name vom jeweiligen Objekt abhängt, was das Wesen von Objektvariablen ausmacht.

Denken Sie daran, dass Sie auf die Variablen und Methoden des gleichen Objekts nur mit Hilfe der Variablen self Bezug nehmen können. Dies wird als Attribut-Referenzierung bezeichnet.

Wir sehen in diesem Programm auch die Benutzung von Dokumentations-Strings sowohl für Klassen als auch für Methoden. Wir können auf den Dokumentations-String der Klasse zur Laufzeit mit Person.__doc__ zugreifen, und mit Person.sagHallo.__doc__ auf den Dokumentations-String der Methode.

Ganz ähnlich zur Methode __init__ gibt es eine andere spezielle Methode __del__, die aufgerufen wird, wenn ein Objekt aufhört zu leben, d.h. wenn es nicht mehr gebraucht wird und der von ihm belegte Speicher an das System zur Wiederverwendung zurückgegeben wird. In dieser Methode erniedrigen wir einfach den Zähler Person.bevoelkerung um 1.

Die __del__-Methode wird automatisch aufgerufen, wenn das Objekt nicht mehr gebraucht wird, und es gibt keine Garantie dafür, wann dies der Fall ist. Wenn Sie dies explizit tun wollen, müssen Sie einfach die del-Anweisung benutzen, die wir bereits aus früheren Beispielen kennen.

Anmerkung für C++/Java/C#-Programmierer

In Python sind alle Mitglieder, d.h. alle Attribute einschließlich der Felder public, und alle Methoden sind virtual.

Eine Ausnahme: Wenn Sie Felder verwenden, deren Namen mit einem doppelten Unterstrich beginnt, so wie __privatvar, dann modifiziert Python den Namen so, dass daraus praktisch eine private Variable wird.

Daraus hat sich die Konvention ergeben, dass Variablen, die nur innerhalb der Klasse oder des Objekts benutzt werden, mit einem Unterstrich beginnen sollten, während alle anderen Namen öffentlich sind und von anderen Klassen/Objekten benutzt werden können. Denken Sie daran, dass dies nur eine Konvention ist, und nicht von Python erzwungen wird (außer bei Variablen, deren Name mit einem doppelten Unterstrich beginnt).

Beachten Sie auch, dass die __del__-Methode dem Konzept eines Destruktors entspricht.