Seite 1 von 1

__getitem__ zu eigener Methode inkonsistent?

Verfasst: Mittwoch 29. September 2010, 09:46
von Panke
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

Re: __getitem__ zu eigener Methode inkonsistent?

Verfasst: Mittwoch 29. September 2010, 09:56
von EyDu
Was erwartest du, wenn du at und at2 vertauscht? ;-)

Code: Alles auswählen

a.at(point)
a.at2(*point)

Re: __getitem__ zu eigener Methode inkonsistent?

Verfasst: Mittwoch 29. September 2010, 10:04
von Rebecca
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...

Re: __getitem__ zu eigener Methode inkonsistent?

Verfasst: Mittwoch 29. September 2010, 10:09
von 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.

Re: __getitem__ zu eigener Methode inkonsistent?

Verfasst: Mittwoch 29. September 2010, 10:14
von Panke
Danke euch, den Unterschied zw. "Tupelkonstruktor" und Argumenttrenner hab ich da übersehen.

EyDu: Das hilft mir leider nicht :-)