2014-11-04 8 views
0

. Этот реестр похож на this question I asked. Внутри класса у меня есть реестр (в виде списка на этот раз) всех экземпляров этого класса. Экземпляр инициализируется некоторыми координатами, но они будут изменены, поскольку пользователь использует программу. Я сделал функцию, которая сбрасывает эти координаты (упрощенная версия)Функция не будет успешно завершаться над экземплярами класса, если содержимое не вводится вручную в консоли iPython.

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(), а затем попробуйте их снова нарисовать, некоторые из них будут сброшены и больше не будут отображаться на сюжете (как и ожидалось), но примерно половина показывается.

ответ

2

Вы косвенно мутируете Foobar._registry, когда вы перебираете его. Это незаконно и может теоретически привести к чему-либо, от хорошей работы до переформатирования вашего жесткого диска, но на практике это обычно означает, что вы в конечном итоге пропускаете некоторые из значений.

Самое простое изменение перебрать копию: for item in Foobar._registry[:]:

+0

ARGH, и я думал, там было что-то сложное и странное происходит – binaryfunt

 Смежные вопросы

  • Нет связанных вопросов^_^