python json object_pairs_hook 字典解码为 None

python json object_pairs_hook dictionary decoded to None

我在使用 python 标准 json 库时偶然发现了一个非常令人惊讶的观察结果,更具体地说是在从那里使用 object_pairs_hook 时。

这是我的数据:

items.json:
--
{
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
}
--

这是我的最低工作代码:

Jupyter QtConsole 4.3.1
Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

import json

def dummy_hook(input):
    print("INPUT:",input)


filename = r'items.json'
with open(filename, 'r') as f:
    data = json.load(f,object_pairs_hook=dummy_hook)

令我惊讶的是,结果是这样的:

INPUT: [('value', 'New'), ('onclick', 'CreateNewDoc()')]
INPUT: [('value', 'Open'), ('onclick', 'OpenDoc()')]
INPUT: [('value', 'Close'), ('onclick', 'CloseDoc()')]
INPUT: [('menuitem', [None, None, None])]

特别是,您会发现具有 "value"/"onclick" 对的三个词典已被解码为 None。这对我来说是个问题,因为我一直希望对这些进行一些进一步的操作。

问题:这是预料之中的吗?我在这里做错了什么吗?

编辑: 所以把钩子函数改成:

def dummy_hook(input):
    print("INPUT:",input)
    return 7

确实将打印结果更改为:

INPUT: [('value', 'New'), ('onclick', 'CreateNewDoc()')]
INPUT: [('value', 'Open'), ('onclick', 'OpenDoc()')]
INPUT: [('value', 'Close'), ('onclick', 'CloseDoc()')]
INPUT: [('menuitem', [7,7,7])]

如何添加一个return语句来改变解码结果,我还是不明白。但是,是的,原则上,这解决了问题。

我认为你的函数 dummy_hook 应该 return 一个值。在你的情况下,可能是相同的输入。

object_pairs_hook is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the dict. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict() will remember the order of insertion). If object_hook is also defined, the object_pairs_hook takes priority.

来自:https://docs.python.org/3.6/library/json.html#json.load