[英]Why does my code generate an __setitem__ error when using __iadd__ in contained item?
谁能告诉我为什么这段代码抱怨容器上没有__setitem__
? 我以为我只需要容器上的__getitem__
来获取项目,然后__iadd__
来设置值,不知道为什么它会期待__setitem__
class Item:
def __init__(self):
pass
def __iadd__(self, value):
print 'added: ' + value
return self
class Container:
def __init__(self):
self.__items = {
'foo': Item()
}
def __getitem__(self, name):
return self.__items[name]
if __name__ == '__main__':
# works!
con = Container()
item = con['foo']
item += 'works!'
# wtf?
con['foo'] += "what's going on?"
# output:
# added: works!
# added: what's going on?
# Traceback (most recent call last):
# File "foo.py", line 27, in <module>
# con['foo'] += "what's going on?"
# AttributeError: Container instance has no attribute '__setitem__'
谜语我:会发生什么事,如果你使用+=
上一个不变的类型,就像int
? 你能明白为什么在[]
返回的值上调用+=
还需要调用__setitem__
吗?
真正的诀窍是理解python中有一个=
中的任何运算符都涉及一个赋值,因为它需要能够以预期的方式处理不可变类型。
为清楚起见,请考虑以下事项:
>>> a = 10*10**9
>>> b = a
>>> a is b
True
>>> a += 1
>>> a is b
False
显然, a
被指定为引用新值。 因此,它认为当您对__getitem__
返回的值执行+=
时会发生同样的情况。
不幸的是,python文档非常糟糕,说明这将是会发生什么,但正如另一个答案指出的反编译,它显然确实,并且必须正确处理存储在可变容器中的不可变类型。
基本上,
con['foo'] += "what's going on?"
编译成如下:
item = con['foo']
item += "what's going on?"
conf['foo'] = item
你可以看到,反编译代码,如:
2 0 LOAD_GLOBAL 0 (con)
3 LOAD_CONST 1 ('foo')
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 2 ("what's going on?")
13 INPLACE_ADD
14 ROT_THREE
15 STORE_SUBSCR
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.