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
В приведенном выше урезанном коде я не ожидаю присвоения элемента, но, очевидно, он происходит в отмеченной строке и выдает следующее исключение:
File "nethogs2.py", line 130, in __iadd__
self[epoch] += traffic
TypeError: 'TrafficData' object does not support item assignment
Однако, если я вместо этого использую предыдущие 2 закомментированные строки, исключение не выдается.
На мой взгляд, 2 должны вести себя одинаково. self[epoch]
возвращает ссылку на объект, и он изменяется на месте через эти объекты __iadd__
. Что я тут недопонимаю? Я часто сталкиваюсь с этой проблемой при использовании словарей.
Update0
Вероятно, стоит указать, что для значений в self.__data
определено __iadd__
, но не __add__
, и я бы предпочел изменить это значение, если это возможно. Я также хотел бы избежать создания метода __setitem__
.
Update1
Ниже приведен тестовый пример, демонстрирующий проблему, я оставил приведенный выше код для существующих ответов.
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]