[Tutor] overriding brackets in lvalue assignment possible?

Zachary Ware zachary.ware+pytut at gmail.com
Tue Dec 27 12:01:15 EST 2016


On Tue, Dec 27, 2016 at 10:48 AM, James Hartley <jjhartley at gmail.com> 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?

Hi James,

You're looking for __setitem__(), see
https://docs.python.org/3/reference/datamodel.html#object.__setitem__

Hope this helps,
-- 
Zach


More information about the Tutor mailing list