Reputation: 105037
I am trying to use
__getitem__(self, x, y):
on my Matrix class, but it seems to me it doesn't work (I still don't know very well to use python). I'm calling it like this:
print matrix[0,0]
Is it possible at all to use more than one argument? Thanks. Maybe I can use only one argument but pass it as a tuple?
Upvotes: 57
Views: 26682
Reputation: 955
I learned today that you can pass double index to your object that implements getitem, as the following snippet illustrates:
class MyClass:
def __init__(self):
self.data = [[1]]
def __getitem__(self, index):
return self.data[index]
c = MyClass()
print(c[0][0])
I guess this is nothing fancy: the second [0]
is merely accessing elements of the builtin [1]
.
Upvotes: 0
Reputation: 121
You can directly call __getitem__
instead of using brackets.
Example:
class Foo():
def __init__(self):
self.a = [5, 7, 9]
def __getitem__(self, i, plus_one=False):
if plus_one:
i += 1
return self.a[I]
foo = Foo()
foo[0] # 5
foo.__getitem__(0) # 5
foo.__getitem__(0, True) # 7
Upvotes: 0
Reputation: 8066
__getitem__
only accepts one argument (other than self
), so you get passed a tuple.
You can do this:
class matrix:
def __getitem__(self, pos):
x,y = pos
return "fetching %s, %s" % (x, y)
m = matrix()
print m[1,2]
outputs
fetching 1, 2
See the documentation for object.__getitem__
for more information.
Upvotes: 91
Reputation: 881477
Indeed, when you execute bla[x,y]
, you're calling type(bla).__getitem__(bla, (x, y))
-- Python automatically forms the tuple for you and passes it on to __getitem__
as the second argument (the first one being its self
). There's no good way[1] to express that __getitem__
wants more arguments, but also no need to.
[1] In Python 2.*
you can actually give __getitem__
an auto-unpacking signature which will raise ValueError
or TypeError
when you're indexing with too many or too few indices...:
>>> class X(object):
... def __getitem__(self, (x, y)): return x, y
...
>>> x = X()
>>> x[23, 45]
(23, 45)
Whether that's "a good way" is moot... it's been deprecated in Python 3 so you can infer that Guido didn't consider it good upon long reflection;-). Doing your own unpacking (of a single argument in the signature) is no big deal and lets you provide clearer errors (and uniform ones, rather than ones of different types for the very similar error of indexing such an instance with 1 vs, say, 3 indices;-).
Upvotes: 35
Reputation: 76653
No, __getitem__
just takes one argument (in addition to self
). In the case of matrix[0, 0]
, the argument is the tuple (0, 0)
.
Upvotes: 5