Python defaultdict 在设置 default_factory 时抛出 KeyError ?

问题描述

我正在开发一个使用 tkinter 构建 gui 和字典(存储在 json 文件中)来保存设置的小程序。这是相关代码

导入:

from collections import defaultdict
from json import dump,load

定义:

def vivdict(preload={}):
    return defaultdict(vivdict,preload)

加载:

try:
    with open('config.json','r') as jsonFile:
        self._config = vivdict(load(jsonFile))
except FileNotFoundError:
    self._config = vivdict()

这是我得到的错误

Exception in Tkinter callback
Traceback (most recent call last):
  File "c:/Users/Leonhard/Documents/git/changeMAC/changeMAC.py",line 97,in _cbDropdown
    var = self._config['adapterSettings'][self._currentAdapter]['changeOnRestart']
KeyError: '0003'

During handling of the above exception,another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Leonhard\AppData\Local\Programs\Python\python38\lib\tkinter\__init__.py",line 1883,in __call__
    return self.func(*args)
  File "c:/Users/Leonhard/Documents/git/changeMAC/changeMAC.py",line 110,in _cbCheckbutton
    self._config['adapterSettings'][self._currentAdapter]['changeOnRestart'] = self._tkvar2.get()
KeyError: '0003

我很困惑,因为设置了 default_factory 的 defaultdict 不应该抛出 KeyError?对吗?

解决方法

您说 defaultdict 不能抛出 KeyError 是正确的,但请查看您的代码。首先执行 self._config['adapterSettings'],然后使用 [self._currentAdapter] 对其进行索引。我认为问题可能在于 self._config['adapterSettings'] 是一个普通的 dict,因此您需要更改加载脚本以将 load(jsonFile) 返回的所有元素转换为 defaultdict。>

将您的 vivdict 函数更改为:

def vivdict(preload={}):
    for key,value in preload.items():
        if isinstance(value,dict): # Convert all `dict`s to `defaultdict`
            preload[key] = vivdict(value)
    return defaultdict(vivdict,preload)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...