__getitem__ zu eigener Methode inkonsistent?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

Hallo,

ich habe eine Klasse, die neben u.a. ein zwei-dimensionales Feld verwaltet. Auf die Feldelemente möchte ich per
[]-Operator und über eine eigene Methode zugreifen. Dabei fällt mir auf, dass sich __getitem__ nicht ganz wie eine normale Methode verhält.

Beispielcode

Meine Fragen: Warum verhält sich __getitem__ da anders als "normale" Funktionen und wo finde ich das in der Doku?

Gruß, Panke
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Was erwartest du, wenn du at und at2 vertauscht? ;-)

Code: Alles auswählen

a.at(point)
a.at2(*point)
Das Leben ist wie ein Tennisball.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

getitem verhaelt sich wie eine normale Funktion. Du benutzt es nur nicht wie eine normale Funktion. Die Frage ist halt, was tut [,]? Wie ruft es getitem auf?

Edit: Kann nicht tippen...
Zuletzt geändert von Rebecca am Mittwoch 29. September 2010, 10:13, insgesamt 1-mal geändert.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
lunar

@Panke: ".__getitem__()" ist eine ganz normale Methode, und verhält sich beim Aufruf auch so. Dein Quelltext aber ruft ".__getitem__" ja nicht wie jede andere Methode auf, sondern verwendet den Indexzugriff. Der ist eben nicht dasselbe wie ein Methodenaufruf (sonst wäre er ja reichlich überflüssig), und unterliegt infolgedessen insbesondere einer eigenen Grammatik-Regel (vgl. Sprachreferenz, Subscriptions) vs. Calls).

Grundsätzlich ist das Argument des Indexoperators eben ein ganz normaler Ausdruck, so dass das Komma zur Erzeugung eines Tupels führt. Das Ergebnis dieses Ausdrucks wird dann als einziges Objekt an ".__getitem__()" übergeben. Dagegen sind Argumentlisten bei Aufrufen eine Sache für sich, das Komma dient dabei zur Trennung der Argumente.

Falls es sich um ein praktisches Problem handelt, dann verzichte doch einfach auf die zusätzliche Methode, schließlich gilt: "There should be one-- and preferably only one --obvious way to do it." Alternativ kannst Du ".at()" wie folgt implementieren:

Code: Alles auswählen

def at(self, x, y=None):
    if y is not None:
        return self.array[x][y]
    else:
        x, y = x
        return self.array[x][y]
Dann kannst Du ".at()" sowohl mit einem einzigen Tupel als Argument aufrufen (".at(point)") als auch mit zwei Zahlen (".at(1, 2)"), so dass sich ".at()" von außen zumindest ähnlich verhält wie der Indexzugriff.
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

Danke euch, den Unterschied zw. "Tupelkonstruktor" und Argumenttrenner hab ich da übersehen.

EyDu: Das hilft mir leider nicht :-)
Antworten