Я наткнулся на очень удивительное наблюдение при работе со стандартной библиотекой json Python, а точнее при использовании 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])]
В частности, вы поймете, что три словаря с парами «значение» / «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 возвращает None, да, это ожидаемое поведение.
Вопрос не столько в том, что возвращает dummy_hook, поскольку это, вероятно, ясно из определения функции, сколько в том, почему список словарей из исходного файла json декодируется в список None и зачем добавлять оператор return в dummy_hook меняет это поведение.
Я не уверен, что вы не понимаете. Результат функции используется как значение декодированного объекта. Ваша первая функция всегда возвращала None, а вторая всегда возвращает 7 .... эти объекты будут декодированы как None и 7`.






Думаю, ваша функция dummy_hook должна возвращать значение. В вашем случае, возможно, такой же ввод.
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
Я до сих пор не понимаю, почему, но да, это решило эту проблему.
Нужно что-то вернуть от
dummy_hook()