Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload instance[key] += val

Tags:

python

jython

I am writing a Java collection class that is meant to be used with Jython. I want end users to be able to manipulate the collection this way:

myCollection = MyJavaCollection()
myCollection[0] += 10.;
a = myCollection[0]; //a = 10
myCollection[0] += 20.;
b = myCollection[0]; //b = 20

What I find in the Python documentation is the following methods:

  • __getitem__ and __setitem__ methods should do the job for bracket operator overloading.

  • __iadd__ method is the good candidate for the +=.

How can I mix both to do want I want ?

like image 937
David Avatar asked Jul 23 '15 15:07

David


1 Answers

Note that myCollection[0] += 10.; will really be interpreted something like:

myCollection.__setitem__(0,  myCollection.__getitem__(0).__iadd__(10.))

Therefore, to make this work you need to implement:

  • __getitem__ and __setitem__ on MyJavaCollection; and
  • __iadd__ (or __add__, which Python will fall back to if __iadd__ isn't implemented) on whatever .__getitem__ is going to return, not MyJavaCollection itself - if it will return something that already implements addition, like the floats in your example, you're fine.

A quick demonstration:

>>> class Container(object):

    def __init__(self, contained):
        self.contained = contained

    def __getitem__(self, key):
        print "Container.__getitem__"
        return self.contained

    def __setitem__(self, key, val):
        print "Container.__setitem__"
        self.contained = val


>>> class Contained(object):

    def __add__(self, other):
        print "Contained.__add__"
        return "foo"


>>> test = Container(Contained())
>>> test[0] += 1
Container.__getitem__
Contained.__add__
Container.__setitem__
>>> test.contained
'foo'
like image 124
jonrsharpe Avatar answered Sep 24 '22 00:09

jonrsharpe