在下面的示例中,如果数据是通过__setitem__
设置的,则有一个具有=
- 方法的类可以正常工作。但是,如果使用list
方法隐式设置类型.append
的数据,则不会调用__setitem__
- 方法。是否有某种方法可以确保在设置或修改数据时调用__setitem__
(或类似“__moditem__
”之类的东西)?
class MyClass(object):
data = {}
def __setitem__(self, key, value):
self.data[key] = value
print "I do not like change."
def __getitem__(self, item):
return self.data[item]
c = MyClass()
c['list'] = ['hello'] #does invoke setitem
c['list'].append('world') #does not invoke __setitem__
处理这个问题的适当方法是什么?当然可以用
代替最后一行c['list'] = c['list'] + ['world']
但是如果这个类在类库中,那么用户可能不知道。 :/
答案 0 :(得分:2)
__setitem__
,而不是在改变包含的元素时调用。容器无法监控碰巧碰到的物品何时发生变化。毕竟考虑这段代码:
c = MyClass()
c['list'] = ['hello'] # Invokes setitem
foo = c['list'] # Grabs a reference to the object just put into the container
foo.append('world') # setitem is, of course, not invoked
如果您发现自己想要这样做,您可能希望容器保留(或至少返回),而不是标准列表类型和诸如此类的,但代理报告回中央数据存储区。 xml.etree
模块就是这种事情的一个很好的例子。
答案 1 :(得分:1)
__setitem__
仅通过以下语法调用:
obj[key] = value # this equals to obj.__setitem__(key, value)
在其他情况下,当您使用obj[key]
时调用__getattr__
。
例如:
class MyClass(object):
data = {}
def __setitem__(self, key, value):
self.data[key] = value
print "__setitem__ called"
def __getitem__(self, item):
print "__getitem__ called"
return self.data[item]
c = MyClass()
c['list'] = ['hello'] # __setitem__ called
c['list'].append('world') # __getitem__ called
换句话说,在使用c ['list']的最后一行中,首先调用__getitem__
并返回指向上面列表['hello']的初始化的指针。之后,调用此append
方法。