class TrafficData(object):
def __init__(self):
self.__data = {}
def __getitem__(self, epoch):
if not isinstance(epoch, int):
raise TypeError()
return self.__data.setdefault(epoch, ProcessTraffic())
def __iadd__(self, other):
for epoch, traffic in other.iteritems():
# these work
#existing = self[epoch]
#existing += traffic
# this does not
self[epoch] += traffic # here the exception is thrown
return self
In the above trimmed down code, I do not expect an item assignment, yet apparently one is occurring on the marked line, and throwing the following exception:
File "nethogs2.py", line 130, in __iadd__
self[epoch] += traffic
TypeError: 'TrafficData' object does not support item assignment
However if I instead use the preceding 2 commented out lines, no exception is thrown.
As I see it, the 2 should behave in the same way. self[epoch]
returns a reference to an object, and it's modified in place through that objects __iadd__
. What am I misunderstanding here? I frequently run into this problem when using dictionaries.
Update0
It's probably worth pointing out that the values in self.__data
have __iadd__
defined, but not __add__
, and I'd much prefer to modify the value in place if possible. I would also like to avoid creating a __setitem__
method.
Update1
Below is a test case demonstrating the problem, I've left the code above for existing answers.
class Value(object):
def __init__(self, initial=0):
self.a = initial
def __iadd__(self, other):
self.a += other
return self
def __str__(self):
return str(self.a)
class Blah(object):
def __init__(self):
self.__data = {}
def __getitem__(self, key):
return self.__data.setdefault(key, Value())
a = Blah()
b = a[1]
b += 1
print a[1]
a[1] += 2
print a[1]