2009-11-06 15 views
18

Próbuję użyćMożliwe użycie więcej niż jednego argumentu na __getitem__?

__getitem__(self, x, y): 

na mojej klasy Matrix, ale wydaje mi się, że nie działa (I nadal nie wiem bardzo dobrze używać Pythona). Dzwonię to tak:

print matrix[0,0] 

Czy to w ogóle możliwe, aby korzystać z więcej niż jednego argumentu? Dzięki. Może mogę użyć tylko jednego argumentu, ale przekazać go jako krotkę?

Odpowiedz

34

__getitem__ akceptuje tylko jeden argument (inny niż self), więc przekazuje się krotkę.

Można to zrobić:

class matrix: 
    def __getitem__(self, pos): 
     x,y = pos 
     return "fetching %s, %s" % (x, y) 

m = matrix() 
print m[1,2] 

wyjścia

fetching 1, 2 

Zobacz http://docs.python.org/reference/datamodel.html#object.getitem więcej informacji

3

Nie, __getitem__ przyjmuje tylko jeden argument (oprócz self). W przypadku matrix[0, 0], argumentem jest krotka (0, 0).

21

Rzeczywiście, podczas wykonywania bla[x,y], dzwonisz type(bla).__getitem__(bla, (x, y)) - Python automatycznie form krotkę dla ciebie i przekazuje ją jako __getitem__ jako drugi argument (pierwszy to jego self). Nie ma dobrego sposobu, aby [1] wyrazić, że __getitem__ chce więcej argumentów, ale także nie ma potrzeby.



[1] W Pythonie 2.* rzeczywiście można dać __getitem__ auto-rozpakowywania podpis, który podniesie ValueError lub TypeError kiedy indeksowanie zbyt wiele lub zbyt mało indeksów .. .:

>>> class X(object): 
... def __getitem__(self, (x, y)): return x, y 
... 
>>> x = X() 
>>> x[23, 45] 
(23, 45) 

czy to „dobra droga” jest dyskusyjny ... to już przestarzałe w Pythonie 3 więc można wnioskować, że nie zrobił Guido uważaj na to dobre po długiej refleksji ;-). Wykonanie własnego rozpakowania (pojedynczego argumentu w podpisie) nie jest wielkim problemem i pozwala zapewnić wyraźniejsze błędy (i jednolite, a nie różne typy dla bardzo podobnego błędu indeksowania takiej instancji za pomocą 1 na przykład, powiedzmy, 3 indeksy ;-).

+0

Moja wiedza na temat porzucania rozpakowywania argumentów w 3.x nie była taka, że ​​"Guido nie uważał tego za dobre", ale więcej, że prawie nikt nie wiedział, że funkcja istniała nawet w tym języku i znacznie komplikowała kompilator . –

+0

@Laurence, yep - skomplikowane i bardzo rzadko używane -> niedobrze! -) –

+2

Używałem go regularnie i było całkiem przyjemnie, ale problem polegał na tym, że skomplikowane odbicie. Będę tęsknił głównie za jej użyciem w funkcjach lambda. – Casebash

Powiązane problemy