这使用类似于this question I asked的注册表。在一个类中,我有一个该类的所有实例的注册表(这次是一个列表的形式)。使用某些坐标初始化实例,但这些将在用户使用程序时更改。我已经创建了一个重置这些坐标的函数(简化版)
class Foobar:
_registry = []
def __init__(self, position=[0,0,0], direction=[0,0,1]):
self._pos = position # can change later
self._pos0 = position # stored static copy of initial position
self._dir = direction
self._dir0 = direction # stored initial direction
self._registry.append(self) # adds instance to registry
...
def remove(self):
Foobar._registry.remove(self) # removes instance from registry
def reset(self):
self.remove()
Foobar.__init__(self, self._pos0, self._dir0)
# re-initialises instance with starting parameters
...
def reset_all():
# note: outside of Foobar
for item in Foobar._registry:
item.reset()
现在,如果我这样做,这是有效的
>>> A = Foobar([0,0,0], [0,0,1])
>>> A.do_something_that_adds_more_pos_&_dir_vectors()
>>> B = Foobar(... # same sort of thing. C, D etc
>>> A.reset()
>>> B.reset()
>>> C.reset()
>>> D.reset()
那些都重置好了。如果我进入IPython控制台
>>> for item in Foobar._registry:
... item.reset()
所有对象都重置正常。但是,如果我改为reset_all()
,我发现有些实例会重置,而其他实例则不会重置。如果我继续做reset_all()
最终他们都会重置,但不是一次性。发生了什么事?!
额外信息:我将位置和方向向量附加到这些对象。然后我绘制了矢量所指示的路径。如果我尝试reset_all()
然后再次尝试绘制它们,其中一些会被重置并且不再显示在图上(如预期的那样),但大约有一半仍会出现。
答案 0 :(得分:2)
当你迭代它时,你间接地突变Foobar._registry
。这是非法的,理论上可以导致从正常工作到重新格式化硬盘的任何事情,但实际上它通常意味着你最终会跳过某些值。
最简单的改变是迭代副本:for item in Foobar._registry[:]: