简体   繁体   English

如何解决这个python错误? RuntimeError:字典在迭代期间改变了大小

[英]How to fix this python error? RuntimeError: dictionary changed size during iteration

it gives me this error: 它给了我这个错误:

Exception in thread Thread-163:
Traceback (most recent call last):
  File "C:\Python26\lib\threading.py", line 532, in __bootstrap_inner
    self.run()
  File "C:\Python26\lib\threading.py", line 736, in run
    self.function(*self.args, **self.kwargs)
  File "C:\Users\Public\SoundLog\Code\Código Python\SoundLog\SoundLog.py", line 337, in getInfo
    self.data1 = copy.deepcopy(Auxiliar.DataCollection.getInfo(1))
  File "C:\Python26\lib\copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "C:\Python26\lib\copy.py", line 254, in _deepcopy_dict
    for key, value in x.iteritems():
RuntimeError: dictionary changed size during iteration

while executing my python program. 在执行我的python程序时。

How can I avoid this to happen? 我怎样才能避免这种情况发生?

Thanks in advance ;) 提前致谢 ;)

The normal advice, as per the other answers, would be to avoid using iteritems (use items instead). 根据其他答案,正常的建议是避免使用iteritems (改为使用items )。 That of course is not an option in your case, since the iteritems call is being done on your behalf deep in the bowels of a system call. 那当然不是你的选择,因为iteritems调用是在你的系统调用的深处代表你完成的。

Therefore, what I would suggest, assuming Auxiliar.DataCollection.getInfo(1) returns a dictionary (which is the one that's changing during the copy) is that you change your deepcopy call to: 因此,我建议,假设Auxiliar.DataCollection.getInfo(1)返回一个字典(在复制期间正在更改的字典)是您将deepcopy调用更改为:

self.data1 = copy.deepcopy(dict(Auxiliar.DataCollection.getInfo(1)))

This takes a "snapshot" of the dict in question, and the snapshot won't change, so you'll be fine. 这需要有问题的dict的“快照”,快照不会改变,所以你会没事的。

If Auxiliar.DataCollection.getInfo(1) does not return a dict, but some more complicated object which includes dicts as items and/or attributes, it will be a bit more complicated, since those dicts are what you'll need to snapshot. 如果Auxiliar.DataCollection.getInfo(1) 没有返回dict,但是一些更复杂的对象(包括dicts作为项和/或属性),它会更复杂一些,因为那些dicts是你需要快照的。 However, it's impossible to be any more specific in this case, since you give us absolutely no clue as to the code that composes that crucial Auxiliar.DataCollection.getInfo(1) call!-) 但是,在这种情况下,不可能更具体,因为你完全不知道组成关键Auxiliar.DataCollection.getInfo(1)调用的代码! - )

Although this thread is nearly 2 years old I have experienced a similar problem: 虽然这个线程已有近2年的历史,但我遇到了类似的问题:

I have a producer/consumer-like system based on the Queue module. 我有一个基于Queue模块的生产者/消费者类系统。 My worker-class' run-method is defined like this: 我的工人类'run-method定义如下:

def run(self):
    while True:
    a, b, c = Worker._Queue.get()
    # do some stuff
    ...
    self.notify() # notify observers
    Worker._Queue.task_done()

The main-class defines an update-method for the notify of the worker to collect the data and stores it in a dictionary. main-class定义了一个update-method,用于通知工作者收集数据并将其存储在字典中。 As multiple threads may change the dictionary in the main-class this 'critical section' is locked 由于多个线程可能会更改主类中的字典,因此此“关键部分”将被锁定

def update(self, worker):
    Main.indexUpdateLock.acquire()
    # get results of worker
    index = worker.getIndex()
    # copy workers index into the main index
    try:
        for i in index:
            if i in self._index:
                self._index[i] += index[i]
            else:
                self._index[i] = index[i]
    finally:
        # index copied - release the lock
        Main.indexUpdateLock.release()

Now this works in most cases - but somehow sometimes 'for i in index:' in the Main's update-method throws a RuntimeError: dictionary changed size during iteration. 现在这在大多数情况下都有效 - 但是在某些情况下,有时'对于i in index:'在Main的update-method中抛出一个RuntimeError:字典在迭代期间改变了大小。 indexUpdateLock is defined as threading.Lock() or threading.RLock() - the behavior does not change either way I define it. indexUpdateLock定义为threading.Lock()或threading.RLock() - 行为不会改变我定义它的方式。

for i in dict(index): does solve the issue but as index may contain several thousand entries, copying it does not really increase performance imo - that's why I am trying to copy those values directly. 对于我在dict(索引):确实解决了问题,但由于索引可能包含几千个条目,复制它并没有真正提高性能imo - 这就是我试图直接复制这些值的原因。

Although update is defined in Main, through the call of notify() in the worker's thread, update should execute in the worker's thread too and therefore task_done() only be executed when notify() or later on update() has finished processing. 虽然更新是在Main中定义的,但是通过在worker的线程中调用notify(),更新也应该在worker的线程中执行,因此task_done()只有在notify()或更高版本的update()完成处理时才会执行。 And through the definition of the critical section only one thread at a time is allowed to execute this area - or do I have some logical errors here? 通过临界区的定义,一次只允许一个线程执行该区域 - 或者我在这里有一些逻辑错误? I don't really see where the change to the worker's index does come from as the only access to index is in Main.update() and in the the Worker but until task_done() has not executed no other method modifies index inside of Worker 我真的没有看到工作者索引的更改来自哪里,因为唯一的索引访问权限是在Main.update()和Worker中,但是直到task_done()没有执行,没有其他方法修改工作者内部的索引


edit: ok, fixed the issue which was caused by HTMLParser inside of the Worker who sent one additionally entry although the source was already closed - strange behavior though. 编辑:确定,修复了由发送一个额外条目的工作者内部的HTMLParser引起的问题,尽管源已经关闭 - 虽然奇怪的行为。 While for i in index: still produces errors for i in index.keys(): does not, so I'll stick with this 虽然对于索引中的i:仍然在index.keys()中为i生成错误:没有,所以我会坚持这一点

Sounds like your are adding or removing something from the dictionary you are trying to iterate over. 听起来你正在尝试迭代的字典中添加或删除某些内容。 This is not allowed in most languages. 大多数语言都不允许这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python,RuntimeError:字典在迭代过程中更改了大小 - Python, RuntimeError: dictionary changed size during iteration RuntimeError:字典在python迭代期间更改了大小 - RuntimeError: dictionary changed size during iteration in python python RuntimeError:字典在迭代期间改变了大小 - python RuntimeError: dictionary changed size during iteration 如何避免“RuntimeError: dictionary changed size during iteration”错误? - How to avoid "RuntimeError: dictionary changed size during iteration" error? RuntimeError:词典在迭代过程中更改了大小 - RuntimeError: dictionary changed size during iteration RuntimeError:字典在迭代期间使用 defaultdict() 改变了大小 - RuntimeError : dictionary changed size during iteration with defaultdict() RuntimeError:字典在迭代过程中更改了大小-如何解决? - RuntimeError: dictionary changed size during iteration - how to solve? 如何在python 3.7中修复“运行时错误:字典在迭代过程中更改了大小” - how to fix “ runtime error :dictionary changed size during iteration ” in python 3.7 RuntimeError:迭代期间字典改变了大小 - 在defaultdict上使用iteritems进行迭代 - RuntimeError: dictionary changed size during iteration - During Iteration with iteritems on a defaultdict “RuntimeError:字典在迭代期间改变了大小”但它在循环中没有改变 - "RuntimeError: dictionary changed size during iteration" but it's not changed in the loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM