在使用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
应该返回一个值。在你的情况下,也许是同样的输入。
object_pairs_hook是一个可选函数,它将被调用,其结果是使用有序的对列表解码的任何对象文字将使用object_pairs_hook的返回值而不是dict。此功能可用于实现依赖于密钥和值对解码顺序的自定义解码器(例如,collections.OrderedDict((将记住插入顺序(。如果还定义了object_hook,则object_pairs_hook具有优先级。
来自:https://docs.python.org/3.6/library/json.html#json.load