向字典插入键值对触发RuntimeError:dictionary changed size during iteration
你遇到的RuntimeError('dictionary changed size during iteration'),根源并不是修改dict_plugin_info导致的——而是你正在迭代的module.__dict__在循环过程中被修改了。
具体分析
你的循环基于module.__dict__.items()执行,而在循环内部创建实例inst = attr()时,该类的初始化方法(__init__)可能动态修改了module.__dict__(比如向模块中添加新属性、删除已有属性),导致正在迭代的字典大小发生变化,触发Python的保护机制抛出异常。
你之前查阅的资料提到迭代时删除键会报错,但实际上任何改变字典大小的操作(包括添加、删除键),在迭代原字典的过程中都会触发这个错误。
解决步骤
迭代字典的固定副本:
把循环语句改成迭代module.__dict__.items()的列表副本,这样即使原字典后续被修改,也不会影响当前的迭代过程:# 将原循环行修改为: for name, attr in list(module.__dict__.items()):排查类初始化逻辑:
检查PluginInterfaceBase子类的__init__方法,确认是否存在修改module.__dict__的代码(比如setattr(module, "new_attr", value)这类操作)。如果确实有这类需求,建议调整逻辑,避免在迭代模块字典的过程中修改它。
另外,你代码中检查plugin_type是否存在的逻辑可以简化,不需要先转换为keys列表,直接用if plugin_type not in dict_plugin_info:即可——字典的in操作本身就是检查键的存在,效率更高。
内容的提问来源于stack exchange,提问作者Lu Lee

