James Hartley wrote: > I can successfully override __getitem__() for rvalues, but the following > example shows that more is required when used as an lvalue: > > ===8<----- > #!/usr/bin/env python > > class Foo(): > def __init__(self, n): > self.d = dict.fromkeys([i for i in range(0, n)]) > > def __getitem__(self, i): > return self.d[i] > > def main(): > foo = Foo(4) > print(foo[0]) > foo[0] = 2 # not as an lvalue? > print(foo[0]) > > if __name__ == '__main__': > main() > ===8<----- > > Python 3.4 generates the following output when this example is executed: > > None > Traceback (most recent call last): > File "./test.py", line 17, in <module> > main() > File "./test.py", line 13, in main > foo[0] = 2 > TypeError: 'Foo' object does not support item assignment > > I am surprised that the error states that the object itself cannot accept > assignment. From the C++ perspective, the underlying dictionary should be > exposed. Does Python overloading allow use of bracket overriding in > lvalues?
Since Python doesn't allow multiple method definitions with different signatures under the same name there's a dedicated __setitem__() method: >>> class Foo: ... def __setitem__(self, index, value): print("Setting Foo()[{!r}] to {!r}".format(index, value)) ... >>> foo = Foo() >>> foo[42] = "bar" Setting Foo()[42] to 'bar' Of course with the above definition >>> foo[42] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Foo' object does not support indexing but you already know how to fix that. To get a class that works like Python's list or dict while only writing a few methods yourself you can inherit from collections.MutableSequence or MutableMapping. PS: Even without function overloading the developers might have chosen a common method for both, e. g. def __item__(self, index, *args): if args: [value] = args # set item else: result = ... # calculate current value return result The actual choice is cleaner and a tad more efficient. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor