Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by haas.homelinux.net...

Inhaltsverzeichnis
1 Einleitung
2 Überblick über Python
3 Die Arbeit mit Python
4 Der interaktive Modus
5 Grundlegendes zu Python-Programmen
6 Kontrollstrukturen
7 Das Laufzeitmodell
8 Basisdatentypen
9 Benutzerinteraktion und Dateizugriff
10 Funktionen
11 Modularisierung
12 Objektorientierung
13 Weitere Spracheigenschaften
14 Mathematik
15 Strings
16 Datum und Zeit
17 Schnittstelle zum Betriebssystem
18 Parallele Programmierung
19 Datenspeicherung
20 Netzwerkkommunikation
21 Debugging
22 Distribution von Python-Projekten
23 Optimierung
24 Grafische Benutzeroberflächen
25 Python als serverseitige Programmiersprache im WWW mit Django
26 Anbindung an andere Programmiersprachen
27 Insiderwissen
28 Zukunft von Python
A Anhang
Stichwort

Download:
- ZIP, ca. 4,8 MB
Buch bestellen
Ihre Meinung?

Spacer
 <<   zurück
Python von Peter Kaiser, Johannes Ernesti
Das umfassende Handbuch - Aktuell zu Python 2.5
Buch: Python

Python
gebunden, mit CD
819 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1110-9
Pfeil 12 Objektorientierung
  Pfeil 12.1 Klassen
    Pfeil 12.1.1 Definieren von Methoden
    Pfeil 12.1.2 Konstruktor, Destruktor und die Erzeugung von Attributen
    Pfeil 12.1.3 Private Member
    Pfeil 12.1.4 Versteckte Setter und Getter
    Pfeil 12.1.5 Statische Member
  Pfeil 12.2 Vererbung
    Pfeil 12.2.1 Mehrfachvererbung
  Pfeil 12.3 Magic Members
    Pfeil 12.3.1 Allgemeine Magic Members
    Pfeil 12.3.2 Datentypen emulieren
  Pfeil 12.4 Objektphilosophie


Galileo Computing - Zum Seitenanfang

12.3 Magic Members  Zur nächsten ÜberschriftZur vorigen Überschrift

Es gibt in Python eine Reihe spezieller Methoden und Attribute, um Klassen besondere Fähigkeiten zu geben. Die Namen dieser Member beginnen und enden jeweils mit zwei Unterstrichen __. Im Laufe der letzten Kapitel haben Sie bereits zwei dieser sogenannten Magic Members kennengelernt: den Konstruktor namens __init__ und den Destruktor namens __del__.

Der Umgang mit den Methoden und Attributen ist insofern »magisch«, als dass sie in der Regel nicht direkt mit ihrem Namen benutzt, sondern bei Bedarf implizit im Hintergrund verwendet werden. Der Konstruktor __init__ wird beispielsweise immer dann aufgerufen, wenn ein neues Objekt einer Klasse erzeugt wird, auch wenn kein expliziter Aufruf mit zum Beispiel Klassenname.__init__() an der entsprechenden Stelle steht.

Mit vielen Magic Members lässt sich das Verhalten von Built-in Functions und Operatoren für die eigenen Klassen anpassen, sodass die Instanzen Ihrer Klassen beispielsweise sinnvoll mit den Vergleichsoperatoren < und > verglichen werden können.

Wir werden Ihnen im Folgenden eine Liste präsentieren, die häufig genutzte Magic Members mit ihrer Bedeutung auflistet. Aufgrund der großen Anzahl wird dabei bei vielen der besprochenen Methoden und Attribute auf Beispiele verzichtet. Wir bitten Sie, für genauere Informationen Pythons Online-Dokumentation zu konsultieren.


Galileo Computing - Zum Seitenanfang

12.3.1 Allgemeine Magic Members  Zur nächsten ÜberschriftZur vorigen Überschrift

__init__(self[, ...])

Der Destruktor einer Klasse. Wird beim Erzeugen einer neuen Instanz aufgerufen. Näheres können Sie in Abschnitt 12.1.2, »Konstruktor, Destruktor und die Erzeugung von Attributen«, nachlesen.

__del__(self)

Der Destruktor einer Klasse. Wird beim Zerstören einer neuen Instanz aufgerufen. Näheres können Sie in Abschnitt 12.1.2, »Konstruktor, Destruktor und die Erzeugung von Attributen«, nachlesen.

__repr__(self)

Der Rückgabewert von obj.__repr__ gibt an, was repr(obj) zurückgeben soll. Dies sollte nach Möglichkeit gültiger Python-Code sein, der beim Ausführen die Instanz obj erzeugt.

__str__(self)

Der Rückgabewert von obj.__str__ gibt an, was str(obj) zurückgeben soll. Dies sollte nach Möglichkeit eine für den Menschen lesbare Repräsentation von obj sein.

Zugriff auf Attribute anpassen

Die Methoden in diesem Abschnitt dienen dazu, festzulegen, wie Python vorgehen soll, wenn die Attribute einer Instanz gelesen oder geschrieben werden. Da die Standardmechanismen in den meisten Fällen das gewünschte Resultat bewirken, werden Sie diese Methoden nur selten überschreiben.

__dict__

Jede Instanz besitzt ein Attribut namens __dict__, das die Member der Instanz in einem Dictionary speichert.

Die beiden folgenden Code-Zeilen produzieren also das gleiche Ergebnis, vorausgesetzt, obj ist eine Instanz einer Klasse, die ein Attribut »A« definiert:

>>> obj.A 
"Der Wert des Attributs A" 
>>> obj.__dict__["A"] 
"Der Wert des Attributs A"
__getattr__(self, name)

Wird dann aufgerufen, wenn das Attribut mit dem Namen name gelesen wird, aber nicht existiert.

Die Methode __getattr__ sollte entweder einen Wert zurückgeben, der für das Attribut gelten soll, oder einen AttributeError erzeugen.

__getattribute__(self, name)

Wird immer aufgerufen, wenn der Wert des Attributs mit dem Namen name gelesen wird, auch wenn das Attribut bereits existiert.

Implementiert eine Klasse sowohl __getattr__ als auch __getattribute__, wird nur letztere Funktion beim Lesen von Attributen aufgerufen, es sei denn, __getattribute__ ruft selbst __getattr__ auf.


Wichtig
Greifen Sie innerhalb von __getattribute__ niemals mit self.attribut auf die Attribute der Instanz zu, weil dies eine endlose Rekursion zur Folge hätte.

Benutzen Sie stattdessen immer __getattribute__ der Basisklasse, zum Beispiel object.__getattribute__(self, "attribut").


__setattr__(self, name, value)

Die Methode __setattr__ wird immer dann aufgerufen, wenn der Wert eines Attributs per Zuweisung geändert oder ein neues Attribut erzeugt wird. Der Parameter name gibt dabei einen String an, der den Namen des zu verändernden Attributs enthält. Mit value wird der neue Wert übergeben.

Mit __setattr__ lässt sich zum Beispiel festlegen, welche Attribute eine Instanz überhaupt haben darf, indem alle anderen Werte einfach ignoriert oder mit Fehlerausgaben quittiert werden.


Wichtig
Verwenden Sie innerhalb von __setattr__ niemals eine Zuweisung der Form self.attribut = wert, um die Attribute auf bestimmte Werte zu setzen, da dies eine endlose Rekursion bewirken würde: Bei jeder Zuweisung würde __setattr__ erneut aufgerufen.

Um Attribut-Werte mit __setattr__ zu verändern, können Sie auf das Attribut __dict__ zurückgreifen: self.__dict__["attribut"] = wert.


__delattr__(self, name)

Wird aufgerufen, wenn das Attribut mit dem Namen name per del gelöscht wird.

__slots__

Mit dem __slots__-Attribut können die Member einer Instanz in der Klasse genau definiert werden. Normalerweise ist es problemlos möglich, auch nach der Instanziierung neue Attribute und Methoden für eine Instanz zu erstellen bzw. Member zu löschen, wie das folgende Beispiel zeigt:

>>> class Test(object): 
        def __init__(self): 
            self.A = 1 
            self.B = 2 
>>> t = Test() 
>>> t.A 
1 
>>> t.C = 1337 
>>> t.C 
1337 
>>> del t.A 
>>> t.A 
Traceback (most recent call last): 
  File "<pyshell#12>", line 1, in <module> 
    t.A 
AttributeError: 'Test' object has no attribute 'A'

Dieses Verhalten ist oft aus mehreren Gründen nicht erwünscht:

Das dynamische Erstellen und Löschen von Membern kann zu schwer lokalisierbaren Fehlern führen und das Kapselungsprinzip verletzen. Außerdem muss der Interpreter Aufwand treiben, um die Dynamik der Member zu gewährleisten. Gerade bei Klassen, die sehr oft instanziiert werden sollen, kann dies zu Speicher- und Geschwindigkeitsproblemen führen.

Deshalb kann mit __slots__ angegeben werden, welche Member eine Instanz einer Klasse haben darf. Man erzeugt zu diesem Zweck ein statisches Attribut namens __slot__, dem man eine Sequenz der Namen zuweist, die die Attribute und Methoden der Instanzen haben dürfen. Alle Versuche, auf andere Member als die mit __slots__ definierten zuzugreifen, führen dann zu Fehlern. Außerdem benutzt Python für solche Instanzen eine effizientere Technik, um die Attribute und Methoden zu speichern als bei »normalen« Klassen.

Im folgenden Beispiel darf die Klasse Test nur die Attribute namens A und B haben.

>>> class Test(object): 
        __slots__ = ("A", "B") 
        def __init__(self): 
            self.A = 1 
            self.B = 2 
>>> t = Test() 
>>> t.A 
1 
>>> t.C = 1337 
Traceback (most recent call last): 
  File "<pyshell#16>", line 1, in <module> 
    t.C = 1337 
AttributeError: 'Test' object has no attribute 'C' 
>>> del t.A 
>>> t.A 
Traceback (most recent call last): 
  File "<pyshell#12>", line 1, in <module> 
    t.A 
AttributeError: 'Test' object has no attribute 'A'

Wie Sie sehen, schlägt das Erstellen des neuen Attributs C mit einem Attribute Error fehl. Es ist allerdings immer noch möglich, bereits vorhandene Attribute per del zu löschen. Diese können allerdings auch wieder erzeugt werden, sofern sie in der __slots__-Liste stehen.


Wichtig
Eine __slots__-Definition lässt sich nicht auf Subklassen vererben.


Vergleichsoperatoren

Die folgenden Magic Methods dienen dazu, das Verhalten der Vergleichsoperatoren für die Klasse anzupassen. Man nennt diese Anpassung auch Überladen des Operators.

Um beispielsweise zwei Kontoklassen zu vergleichen, kann die Kontonummer herangezogen werden. Damit gibt es eine sinnvolle Interpretation für den Vergleich mit == bei Konten. Die Magic Method für Vergleiche mit == heißt __eq__ (von engl. equal = gleich) und erwartet als Parameter eine Instanz, mit der das Objekt verglichen werden soll, für das __eq__ aufgerufen wurde.

Der folgende Beispielcode erweitert unsere Konto-Klasse aus der Einführung zur Objektorientierung um die Fähigkeit, sinnvoll mit == verglichen zu werden:

class Konto(object): 
    def __init__(self, inhaber, kontonummer, kontostand, 
                       max_tagesumsatz=1500): 
        self.Inhaber = inhaber 
        self.Kontonummer = kontonummer 
        self.Kontostand = kontostand 
        self.MaxTagesumsatz = max_tagesumsatz 
        self.UmsatzHeute = 0 
 
    def __eq__(self, k2): 
        return self.Kontonummer == k2.Kontonummer

Nun erzeugen wir drei Konten, wobei zwei die gleiche Kontonummer haben, und vergleichen sie mit dem ==-Operator. Das Szenario wird natürlich immer ein Wunschtraum für Donald Duck bleiben:

>>> konto1 = Konto("Dagobert Duck", 1337, 9999999999999999) 
>>> konto2 = Konto("Donald Duck", 1337, 1.5) 
>>> konto3 = Konto("Gustav Gans", 2674, "50000") 
>>> konto1 == konto2 
True 
>>> konto1 == konto3 
False

Die Anweisung konto1 == konto2 wird intern von Python beim Ausführen durch konto1.__eq__(konto2) ersetzt.

Neben der __eq__-Methode gibt es eine Reihe weiterer Vergleichsmethoden, die jeweils einem Vergleichsoperator entsprechen. Alle diese Methoden erwarten neben self einen weiteren Parameter, der die Instanz referenzieren muss, mit der self verglichen werden soll.

Die nachfolgende Tabelle zeigt alle Vergleichsmethoden mit ihren Entsprechungen. Die Herkunftstabelle kann Ihnen unter Umständen helfen, sich die Methodennamen und ihre Bedeutung besser zu merken:


Tabelle 12.3  Die Magic Methods für Vergleiche
Methode Operator Herkunft

__lt__(self, other)

<

Lower Than (dt. kleiner als)

__le__(self, other)

<=

Less or Equal (dt. kleiner oder gleich)

__eq__(self, other)

==

Equal (dt. gleich)

__ne__(self, other)

!=

Not Equal (dt. ungleich)

__gt__(self, other)

>

Greater Than (dt. größer als)

__ge__(self, other)

>=

Greater or Equal (dt. größer oder gleich)


Es ist besonders für eher kleine Klassen lästig, immer alle dieser sechs Methoden zu implementieren, bloß damit zwei Instanzen verglichen werden können.

Alternativ kann die Methode __cmp__ verwendet werden.

__cmp__(self, other)

Mit __cmp__ kann eine Methode definiert werden, die es ermöglicht, die Vergleichsoperatoren für die implementierende Klasse zu verwenden, ohne dass dafür die sechs Methoden des vorhergehenden Abschnitts definiert werden müssen.

Die Methode __cmp__ muss einen Zahlenwert zurückgeben, der angibt, ob self oder other den größeren Wert hat oder ob beide identisch sind. Die folgende Tabelle zeigt die möglichen Rückgabewerte und ihre Bedeutungen:


Tabelle 12.4  Die Rückgabewerte von __cmp__
Rückgabewert Bedeutung

Ganzzahl größer als 0

self > other

0

self == other

Ganzzahl kleiner als 0

self < other



Wichtig
Wenn eine Klasse keine der Methoden __cmp__, __eq__ oder __ne__ implementiert, werden Instanzen der Klasse anhand ihrer Identität miteinander verglichen.


__hash__(self)

Die __hash__-Methode einer Instanz bestimmt, welchen Wert die Built-in Function hash für die Instanz zurückgeben soll. Die hash-Werte müssen Ganzzahlen sein und sind insbesondere für die Verwendung von Instanzen als Schlüssel für Dictionarys von Bedeutung.

Die einzige Bedingung für gültige hash-Werte ist, dass Objekte, die bei Vergleichen mit == als gleich angesehen werden, auch den gleichen hash-Wert besitzen.

__nonzero__(self)

Die __nonzero__-Methode sollte einen Wahrheitswert (True oder False) zurückgeben, der angibt, wie das Objekt in eine bool-Instanz umzuwandeln ist.

Ist __nonzero__ nicht implementiert, wird stattdessen der Rückgabewert von __len__ verwendet. Sind beide Methoden nicht vorhanden, werden alle Instanzen der betreffenden Klasse als True behandelt.

__unicode__(self)

Wie __str__, nur dass anstelle einer str-Instanz ein Objekt des Typs unicode zurückgegeben werden muss.

__call__(self[, args...])

Mit der __call__-Methode können die Instanzen einer Klasse wie Funktionen aufrufbar werden.

Das folgende Beispiel implementiert eine Klasse Potenz, die dazu dient, Potenzen zu berechnen. Welcher Exponent dabei verwendet werden soll, wird dem Konstruktor als Parameter übergeben. Durch die __call__-Methode können die Instanzen von Potenz wie Funktionen aufgerufen werden, um Potenzen zu berechnen:

class Potenz(object): 
    def __init__(self, exponent): 
        self.Exponent = exponent 
 
    def __call__(self, basis): 
        return basis ** self.Exponent

Nun kann bequem mit Potenzen gearbeitet werden:

>>> dreier_potenz = Potenz(3) 
>>> dreier_potenz(2) 
8 
>>> dreier_potenz(5) 
125

Galileo Computing - Zum Seitenanfang

12.3.2 Datentypen emulieren  topZur vorigen Überschrift

In Python entscheiden die Methoden, die ein Datentyp implementiert, zu welcher Kategorie von Datentypen er gehört. Deshalb ist es möglich, Ihre eigenen Datentypen wie beispielsweise numerische oder sequenzielle Datentypen »aussehen« zu lassen, indem sie die entsprechende Schnittstelle implementieren.

Sie werden im Folgenden die Methoden kennenlernen, die ein Datentyp implementieren muss, um ein numerischer Datentyp zu sein. Außerdem werden die Schnittstellen von Sequenzen und Mappings behandelt.

Numerische Datentypen emulieren

Ein numerischer Datentyp muss vor allem eine Reihe von Operatoren definieren.

Binäre Operatoren

Als Erstes gibt es da die sogenannten binären Operatoren, die zwei Operanden erwarten. Hierzu zählen unter anderem +, -, * und /.

Alle Methoden zum Überladen von binären Operatoren erwarten einen Parameter, der den zweiten Operanden referenziert. Ihr Rückgabewert muss eine neue Instanz sein, die das Ergebnis der Rechnung enthält.

Wenn Python einen Ausdruck auswertet, der binäre Operatoren enthält, werden intern automatisch die entsprechenden Methoden aufgerufen. Die folgenden beiden Befehle sind vollkommen gleichwertig, wobei die Klammern um die 1 aus syntaktischen Gründen notwendig sind:

>>> 1 + 2 
3 
>>> (1).__add__(2) 
3

Als Beispiel werden wir eine kleine Klasse zum Verwalten von Längenangaben mit Einheiten implementieren, die die Operatoren für Addition und Subtraktion unterstützt.

Die Klasse wird intern alle Maße für die Berechnungen in Meter umwandeln. Ihre Definition sieht dann folgendermaßen aus:

class Laenge(object): 
    Umrechnung = {"m" : 1, "cm" : 0.01, "mm" : 0.001, 
                  "dm" : 10, "km" : 1000, 
                  "ft" : 0.3048,   # Fuss 
                  "in" : 0.0254,   # Zoll 
                  "mi" : 1609344   # Meilen 
                 } 
 
    def __init__(self, zahlenwert, einheit): 
        self.Zahlenwert = zahlenwert 
        self.Einheit = einheit 
 
    def __str__(self): 
        return "%f%s" % (self.Zahlenwert, self.Einheit) 
 
    def __add__(self, other): 
        z = self.Zahlenwert * Laenge.Umrechnung[self.Einheit] 
        z += other.Zahlenwert * Laenge.Umrechnung[other.Einheit] 
        z /= Laenge.Umrechnung[self.Einheit] 
        return Laenge(z, self.Einheit) 
 
    def __sub__(self, other): 
        z = self.Zahlenwert * Laenge.Umrechnung[self.Einheit] 
        z -= other.Zahlenwert * Laenge.Umrechnung[other.Einheit] 
        z /= Laenge.Umrechnung[self.Einheit] 
        return Laenge(z, self.Einheit)

Das Dictionary Laenge.Umrechnung enthält Faktoren, mit denen geläufige Längenmaße in Meter umgerechnet werden. Die Methoden __add__ und __sub__ überladen jeweils den Operator für Addition + bzw. den für Subtraktion , indem sie zuerst die Zahlenwerte beider Operanden gemäß ihrer Einheiten in Meter umwandeln, verrechnen und schließlich wieder in die Einheit des weiter links stehenden Operanden konvertieren.

In der nachstehenden Tabelle sind alle binären Operatoren und die entsprechenden Magic Methods aufgelistet:


Tabelle 12.5  Magic Methods für binäre Operatoren
Operator Magic Method

+

__add__(self, other)

__sub__(self, other)

*

__mul__(self, other)

/

__div__(self, other)

//

__floordiv__(self, other)

**

__pow__(self, other[, modulo])

%

__mod__(self, other)

>>

__lshift__(self, other)

<<

__rshift__(self, other)

&

__and__(self, other)

|

__or__(self, other)

^

__xor__(self, other)


Die Methoden sollten bei erfolgreicher Rechnung das Ergebnis zurückgeben. Ist es nicht möglich, den Operanden other zu verarbeiten, sollte NotImplemented zurückgegeben werden.

Binäre Operatoren mit umgekehrter Operandenreihenfolge

Wenn Python einen Ausdruck der Form Operand1 Operator Operand2 wie beispielsweise 2 * "abc" auswerten soll, wird zuerst versucht, eine passende Methode vom ersten Operanden zu benutzen. Existiert diese nicht oder gibt sie NotImplemented zurück, wird versucht, beim zweiten Operanden eine entsprechende Methode zu finden. Dies geschieht aber nur dann, wenn die beiden Operanden nicht vom gleichen Datentyp sind. Allerdings muss der zweite Operand eine spezielle Methode für vertauschte Operanden implementieren. Die folgende Tabelle listet alle dafür verfügbaren Methodennamen und die entsprechenden Operatoren auf:


Tabelle 12.6  Magic Methods für binäre Operatoren des rechten Operanden
Operator Magic Method

+

__radd__(self, other)

__rsub__(self, other)

*

__rmul__(self, other)

/

__rdiv__(self, other)

//

__rfloordiv__(self, other)

**

__rpow__(self, other[, modulo])

%

__rmod__(self, other)

>>

__rlshift__(self, other)

<<

__rrshift__(self, other)

&

__rand__(self, other)

|

__ror__(self, other)

^

__rxor__(self, other)


Für nicht unterstützte Werte von other sollte auch hier NotImplemented zurückgegeben werden.

Erweiterte Zuweisungen

Neben den Operatoren selbst können auch die erweiterten Zuweisungen überladen werden. Bei einer erweiterten Zuweisung wird ein Gleichheitszeichen benutzt, dem der jeweilige Operator vorangestellt wird:

>>> a = 10 
>>> a += 5 
>>> a 
15

Standardmäßig verwendet Python für solche Zuweisungen den Operator selbst, sodass a += 5 intern wie a = a + 5 ausgeführt wird. Diese Vorgehensweise hat für komplexe Datentypen wie beispielsweise Listen den Nachteil, dass immer eine komplett neue Liste erzeugt werden muss. Deshalb kann man gezielt die erweiterten Zuweisungen anpassen, um die Effizienz des Programms zu verbessern.

In der nachstehenden Tabelle stehen alle Operatoren für erweiterte Zuweisungen und die entsprechenden Methoden:


Tabelle 12.7  Methoden für die erweiterte Zuweisung
Operator Magic Method

+=

__iadd__(self, other)

-=

__isub__(self, other)

*=

__imul__(self, other)

/=

__idiv__(self, other)

//=

__ifloordiv__(self, other)

**=

__ipow__(self, other[, modulo])

%=

__imod__(self, other)

>>=

__ilshift__(self, other)

<<=

__irshift__(self, other)

&=

__iand__(self, other)

|=

__ior__(self, other)

^=

__ixor__(self, other)


Unäre Operatoren

Mit den folgenden Methoden werden die unären Operatoren überladen. Unäre Operatoren erwarten im Gegensatz zu den binären Operatoren nur einen Parameter. Zu den unären Operatoren zählen die Vorzeichen + und , die Built-in Function abs zur Bestimmung des absoluten Werts und die Tilde ~, um das Komplement eines Wertes zu berechnen:


Tabelle 12.8  Magic Methods für die binären Operatoren
Operator Magic Method

+

__pos__(self)

__neg__(self)

abs

__abs__(self)

~

__invert__(self)


Bulit-In Functions und Umwandlung in andere Typen

Zu guter Letzt gibt es einen Satz von Magic Methods, mit dem bestimmt werden kann, welche Werte bestimmte Built-in Functions für sie zurückgeben sollen. Für diesen Zweck existieren die folgenden Methoden:


Tabelle 12.9  Methoden zum Festlegen der Built-in-Rückgabewerte
Built-in Magic Method

complex

__complex__(self)

int

__int__(self)

long

__long__(self)

float

__float__(self)

oct

__oct__(self)

hex

__hex__(self)


__index__(self)

Wenn ein Datentyp außerdem als Index benutzt werden soll, wie er beispielsweise für das Slicing benötigt wird, muss er die parameterlose Methode __index__(self) überschreiben. Der Rückgabewert von __index__ muss eine Ganzzahl (int oder long) sein.

Container emulieren

Mithilfe der folgenden Methoden ist es möglich, eigene sequenzielle oder Mapping-Datentypen zu implementieren, die sich genauso wie Listen oder Dictionarys benutzen lassen.

Wenn Sie einen sequenziellen Datentyp entwickeln möchten, müssen alle Indizes i der Sequenz Ganzahlen sein und die Gleichung 0 <= i < N erfüllen. N ist dabei als Länge der Sequenz definiert.

Alle Mapping-Datentypen sollten zusätzlich zu den nachfolgend besprochenen Magic Methods weitere Methoden implementieren, die in der nachstehenden Tabelle aufgelistet sind: [Wenn Ihnen die hier angegebenen Beschreibungen nicht ausführlich genug sind, können Sie sich noch einmal den Abschnitt 8.6.1, »Dictionary – dict«, ansehen. ]


Tabelle 12.10   Nötige Methoden für Mapping-Typen
Methode Bedeutung

m.keys()

Gibt eine Liste der Schlüssel von m zurück.

m.values()

Gibt eine Liste der Werte von m zurück.

m.items()

Gibt eine Liste der Schlüssel/Wert-Paare von m zurück.

m.has_key(k)

Prüft, ob der Schlüssel k in m existiert.

m.get(k[, d])

Wenn der Schlüssel k in m existiert, wird m[k] zurückgegeben, ansonsten d.

m.clear()

Entfernt alle Elemente aus m.

m.setdefault(k[, x])

Wenn der Schlüssel k in m existiert, wird m[k] zurückgegeben. Gibt es den Schlüssel k nicht in m, wird m[k] auf den Wert x gesetzt und x zurückgegeben.

m.iterkeys()

Gibt einen Iterator über die Schlüssel von m zurück.

m.itervalues()

Gibt einen Iterator über die Werte von m zurück.

m.iteritems()

Gibt einen Iterator über die Schlüssel/Wert-Paare von m zurück.

m.pop(k[, d])

Wenn der Schlüssel k in m existiert, wird m[k] zurückgegeben und danach mit del gelöscht. Gibt es den Schlüssel k nicht in m, so wird d zurückgegeben.

m.popitem()

Gibt ein willkürlich ausgewähltes Schlüssel/Wert-Paar von m zurück und entfernt es anschließend aus m.

m.copy()

Gibt eine Kopie von m zurück.

m.update(b)

Übernimmt alle Schlüssel/Wert-Paare von b in m. Vorhandene Einträge werden dabei überschrieben.


Nun folgt die Besprechung der Magic Methods für sequenzielle und Mapping-Datentypen:

__len__(self)

Liefert eine Ganzzahl zurück, die die Länge der Sequenz oder des Mapping-Objekts angibt.

__getitem__(self, key)

Wird aufgerufen, wenn mit dem []-Operator ein Element des Containers gelesen wird. Der Parameter key gibt dabei den Index des gesuchten Elements an.

Ein sehr einfaches Beispiel gibt immer den Index selbst als Element des Containers zurück:

>>> class MeinContainer(object): 
        def __getitem__(self, key): 
            return key 
>>> obj = MeinContainer() 
>>> obj[10] 
10 
>>> obj[1337] 
1337

Wenn der übergebene Index key ungültig ist, sollte __getitem__ einen IndexError produzieren.

__setitem__(self, key, value)

Muss das Element mit dem Index key auf den Wert value setzen.

Diese Methode sollte nur dann implementiert werden, wenn der Datentyp das Verändern und Hinzufügen von Elementen unterstützen soll.

Bei ungültigen key-Werten sollte ein IndexError erzeugt werden.

__delitem__(self, key)

Muss das Element mit dem Index key aus dem Container entfernen.

Bei ungültigen key-Werten sollte ein IndexError erzeugt werden.

__iter__(self)

Muss einen Iterator über die Werte des sequenziellen Datentyps bzw. über die Schlüssel des Mapping-Typs zurückgeben.

Genaues zu Iteratoren können Sie in Abschnitt 13.5, »Iteratoren«, nachlesen.

__contains__(self, item)

Muss einen Wahrheitswert zurückgeben, der angibt, ob der sequenzielle Datentyp ein Element mit dem Wert von item enthält. Handelt es sich um einen Mapping-Typ, wird geprüft, ob es einen Schlüssel mit dem Wert von item gibt.

Diese Methode wird von den Operatoren in und not in benutzt.

Allerdings ist es nicht notwendig, __contains__ zu implementieren, wenn bereits __iter__ für den Typ definiert worden ist. Mit __contains__ kann der Datentyp nur eine unter Umständen effizientere Prüfung anbieten, da nicht wie bei __iter__ erst die Elemente der Sequenz durchlaufen werden müssen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  
  Zum Katalog
Zum Katalog: Python






Python
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Linux






 Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Praxisbuch Web 2.0






 Praxisbuch Web 2.0


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Praxisbuch Objektorientierung






 Praxisbuch Objektorientierung


Zum Katalog: Einstieg in SQL






 Einstieg in SQL


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo