Reputation: 5680
I want to make the __getitem__
of one class be the sum of it and the item at the same index of another list.
>>> class Test(list):
def __init__(self):
self.extend([1, 2, 3])
def __getitem__(self, index, other):
return self[index] + other[index]
>>> t = Test()
>>> t2 = [4, 5, 6]
However, my two attempts have resulted in errors:
>>> t[5, t2]
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
t[5, t2]
TypeError: __getitem__() missing 1 required positional argument: 'other'
>>> t.__getitem__(5, t2)
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
t.__getitem__(5, t2)
File "<pyshell#17>", line 5, in __getitem__
return self[index] + other[index]
TypeError: __getitem__() missing 1 required positional argument: 'other'
Is it possible to give __getitem__
multiple arguments? If so, how? If not, is there a way to emulate it?
Upvotes: 4
Views: 1750
Reputation: 152795
It is possible because you get a tuple of "indices" in __getitem__
not multiple parameters:
class Test(list):
def __init__(self):
self.extend([1, 2, 3])
def __getitem__(self, value):
# this makes sure that a sequence with exactly 2 elements is passed in: (thanks @ShadowRanger)
index, other = value
return super().__getitem__(index) + other[index]
>>> t = Test()
>>> t2 = [4, 5, 6]
>>> t[2, t2]
9 # 3 + 6
>>> t[1, t2]
7 # 2 + 5
>>> t[0, t2]
5 # 1 + 4
There are some caveats however:
super().__getitem__
so you don't end up in an recursion.__getitem__
if you want to allow normal slicing.Upvotes: 4
Reputation: 22993
Is it possible to give getitem multiple arguments? If so, how? If not, is there a way to emulate it?
Why would want to emulate this? You're missing the point of "magic methods". Python provides you with these methods to give a form of operator overloading. Here is an excerpt from the Python documentation section 3.3. Special method names, that describes what "magic methods" are meant to be used for:
A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names. This is Python’s approach to operator overloading, allowing classes to define their own behavior with respect to language operators.
(emphasis mine)
Furthermore, this makes your class ambiguous to readers of your code who are expected __getitem__
to return a single element.
Since @MSeifert has already given you a way to achieve the behavior you want, I won't post my solution. But I strongly encourage you to create your own custom method. If you still do choose to make changes to the functionality of your __getitem__
method, I highly recommend that you at least document these changes and make it clear that your implementation of __getiem__
has different behavior than the normal implementation.
Upvotes: 1