289
10.4
Zugriff auf Attribute – Sichtbarkeit
bute bergen das Risiko, dass Attribute versehentlich so geändert werden, dass das Objekt in
einen inkonsistenten Zustand gelangt. Betrachten Sie folgendes Beispiel:
Hier treten zwei Probleme auf:
Dem Attribut waehrung wurde ein ungültiger Wert zugewiesen, der in der Menge der
Schlüssel des Dictionarys
wechselkurs nicht vorkommt.
Der Wert des Attributs betrag ist nun eine ganze Zahl (int), obwohl in der Konstruk-
tormethode eigentlich festgelegt ist, dass es sich um eine Gleitkommazahl (
float) han-
deln soll. Wie Sie wissen, kann das Folgen für die Arithmetik haben. Zum Beispiel
werden vom Python-Interpreter Gleitkommazahlen anders dividiert als ganze Zahlen.
10.4.2 Private Attribute
Um Attribute vor öffentlichem Zugriff zu schützen, kann man ihnen einen Namen geben, der
mit ein oder zwei Unterstrichen beginnt. Ein solcherart abgeschirmtes Attribut nennt man in
der objektorientierten Programmierung privat. Python unterscheidet zwischen schwacher
und starker Privatheit.
Stark private Attribute haben Namen, die mit zwei Unterstrichen beginnen und nicht
mit Unterstrichen enden, z.B.
__privat. Es ist nur möglich, innerhalb der Klassendefi-
nition auf ein solches Attribut zuzugreifen.
Die Namen schwach privater Attribute beginnen mit einem einfachen Unterstrich, z.B.
_privat. Diese Namen werden durch from ... import * nicht in den Namensraum
importiert. Damit wird das Risiko von Namenskollisionen verringert. Man kann aber
problemlos auf das Attribut zugreifen, wenn man seinen Namen kennt.
Beispiel:
>>> preis = Geld('EUR', 1000)
>>> preis.waehrung = 'DM'
>>> preis.betrag = 1000
class C(object):
def __init__ (self):
self.__privat = "privat"
self._privat = "schwach privat"
self.oeffentlich ="öffentlich"
>>> c = C()
>>> print(c.oeffentlich)
öffentlich
>>> print(c._privat)
schwach privat
>>> print(c.__privat)
Traceback (most recent call last):
File "<pyshell#52>", line 1, in -toplevel-
Kapitel 10
Definition eigener Klassen
290
Allerdings bieten private Namen keinen wirklichen Schutz vor einem Zugriff von außen.
Attribute, deren Namen mit doppeltem Unterstrich beginnen, werden eigentlich nur ver-
steckt. Sie können ein streng privates Attribut sichtbar machen, in dem Sie dem Attribut-
namen einen Unterstrich und den Namen der Klasse voranstellen:
Sie sehen daran, dass Python – im Unterschied zu anderen Programmiersprachen wie Java –
nicht sehr restriktiv ist. Generell ist Restriktivität in der Python-Community eher verpönt. Man
vertraut darauf, dass die Mitglieder eines Programmierteams sich vernünftig verhalten und
nicht absichtlich in fremde Module Fehler einbauen ("We are all consenting adults here").
Als Anwendungsbeispiel ändern wir die Klasse
Geld so ab, dass alle Attribute privat sind.
Dabei ist es mit einer einfachen Umbenennung nicht getan. Denn für die Ausgabe von Wer-
ten und für die Implementierung der Methode
add() müssen wir – bei aller Privatheit – in
irgendeiner Form auf die Werte der Attribute
betrag und waehrung zugreifen können,
allerdings brauchen wir hier nur lesenden Zugriff, aber keinen schreibenden.
Wir müssen also Vorkehrungen für den kontrollierten Zugriff auf die geschützten Attribute
treffen. Dazu definieren wir zwei Methoden, die das Lesen der Attribute ermöglichen. Wir
nennen sie getBetrag() und getWaehrung().
Außerdem definieren wir zwei Methoden, die eine Änderung der beiden privaten Attribute
ermöglichen, ohne dass das Objekt in einen inkonsistenten Zustand gerät. Die Methode
setBetrag() bewirkt eine Änderung des Attributs __betrag, wobei das übergebene Argu-
ment in den richtigen Datentyp (
float) überführt wird. Die Methode setWaehrung()
ändert das Attribut __waehrung. Dabei prüft sie, ob eine gültige Währungseinheit als Argu-
ment übergeben worden ist, und rechnet den repräsentierten Geldbetrag in die neue Wäh-
rung um.
Hier nun die erweiterte Klassendefinition:
print(c.__privat)
AttributeError: 'C' object has no attribute '__privat'
>>> print(c. _C__privat)
privat
# geld1.py
class Geld(object):
__wechselkurs={'USD':0.84998,
'G B P ':1 . 3 948 0 ,
'E U R ':1 . 0 ,
'J P Y ':0 . 0 071 6 8}
def __init__(self, waehrung, betrag):
self.__waehrung = waehrung
self.__betrag = float(betrag)
def getBetrag(self):
return self.__betrag

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.