Python defaultdict 抛出设置 default_factory 的 KeyError?

Python defaultdict throws KeyError with default_factory set?

我正在开发一个小程序,该程序使用 tkinter 构建图形用户界面和字典(存储在 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) returns 的所有元素转换为 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)