Сериализация удобочитаемых объектов Python
-
03-07-2019 - |
Вопрос
мне нужно хранить структуры Python, состоящие из списков/словарей, кортежей, в удобочитаемом формате.Идея похожа на использование чего-то похожего на соленый огурец, но маринованный огурец небезопасен для человека.Другие варианты, которые приходят мне на ум: ЯМЛ (через ПиЯМЛ и JSON (через простой json) сериализаторы.
Есть ли еще вариант, который приходит вам на ум?
Заранее спасибо.
Решение
В простых случаях на ум приходят pprint() и eval().
Используя ваш пример:
>>> d = {'age': 27,
... 'name': 'Joe',
... 'numbers': [1,
... 2,
... 3,
... 4,
... 5],
... 'subdict': {
... 'first': 1,
... 'second': 2,
... 'third': 3
... }
... }
>>>
>>> from pprint import pprint
>>> pprint(d)
{'age': 27,
'name': 'Joe',
'numbers': [1, 2, 3, 4, 5],
'subdict': {'first': 1, 'second': 2, 'third': 3}}
>>>
Я бы дважды подумал, прежде чем исправить два требования с помощью одного и того же инструмента.Рассматривали ли вы возможность использовать Pickle для сериализации, а затем pprint() (или более причудливую программу просмотра объектов) для людей, просматривающих объекты?
Другие советы
Если это только Список Python, словарь и объект кортежа.- JSON это путь.Он удобен для чтения человеком, очень прост в обращении и не зависит от языка.
Осторожность:Кортежи будут преобразованы в списки в simplejson.
In [109]: simplejson.loads(simplejson.dumps({'d':(12,3,4,4,5)}))
Out[109]: {u'd': [12, 3, 4, 4, 5]}
Если вам нужно больше представлений, чем покрывает JSON, я настоятельно рекомендую проверить ПЁН (Нотация объектов Python)... хотя я считаю, что она ограничена версиями 2.6/3.0 и выше, поскольку она опирается на Аст модуль.Помимо других функций, он обрабатывает экземпляры пользовательских классов и рекурсивные типы данных, что больше, чем предоставляет JSON.
Вам следует проверить jsonpickle (https://github.com/jsonpickle/jsonpickle).Он запишет любой объект Python в файл JSON.Затем вы можете прочитать этот файл обратно в объект Python.Приятно то, что промежуточный файл очень читаем, потому что это json.
Что значит, это не читается человеком???;)
>>> d = {'age': 27,
... 'name': 'Joe',
... 'numbers': [1,2,3,4,5],
... 'subdict': {'first':1, 'second':2, 'third':3}
... }
>>>
>>> import pickle
>>> p = pickle.dumps(d)
>>> p
"(dp0\nS'age'\np1\nI27\nsS'subdict'\np2\n(dp3\nS'second'\np4\nI2\nsS'third'\np5\nI3\nsS'first'\np6\nI1\nssS'name'\np7\nS'Joe'\np8\nsS'numbers'\np9\n(lp10\nI1\naI2\naI3\naI4\naI5\nas."
Хорошо, ну, может быть, это просто требует некоторой практики... или ты можешь схитрить...
>>> import pickletools
>>> pickletools.dis(p)
0: ( MARK
1: d DICT (MARK at 0)
2: p PUT 0
5: S STRING 'age'
12: p PUT 1
15: I INT 27
19: s SETITEM
20: S STRING 'subdict'
31: p PUT 2
34: ( MARK
35: d DICT (MARK at 34)
36: p PUT 3
39: S STRING 'second'
49: p PUT 4
52: I INT 2
55: s SETITEM
56: S STRING 'third'
65: p PUT 5
68: I INT 3
71: s SETITEM
72: S STRING 'first'
81: p PUT 6
84: I INT 1
87: s SETITEM
88: s SETITEM
89: S STRING 'name'
97: p PUT 7
100: S STRING 'Joe'
107: p PUT 8
110: s SETITEM
111: S STRING 'numbers'
122: p PUT 9
125: ( MARK
126: l LIST (MARK at 125)
127: p PUT 10
131: I INT 1
134: a APPEND
135: I INT 2
138: a APPEND
139: I INT 3
142: a APPEND
143: I INT 4
146: a APPEND
147: I INT 5
150: a APPEND
151: s SETITEM
152: . STOP
highest protocol among opcodes = 0
>>>
Вам все равно придется читать маринованный объект из файла, однако вам это не понадобится. load
это.Итак, если это «опасный» объект, вы все равно сможете это выяснить, прежде чем делать load
.Если вы застряли с pickle
, это может быть хорошим вариантом для расшифровки того, что у вас есть.
Чтобы сначала использовать simplejson easy_install простой json:
import simplejson
my_structure = {"name":"Joe", "age":27, "numbers":[1,2,3,4,5], "subdict":{"first":1, "second":2, "third": 3}}
json = simplejson.dumps(my_structure)
в результате json будет:
{"age": 27, "subdict": {"second": 2, "third": 3, "first": 1}, "name": "Joe", "numbers": [1, 2, 3, 4, 5]}
Обратите внимание, что формат словаря почти не изменился, но вам следует выполнить этот шаг, чтобы убедиться в достоверности данных JSON.
Далее можно красиво распечатать результат:
import pprint
pprint.pprint(my_structure)
приводит к:
{'age': 27,
'name': 'Joe',
'numbers': [1, 2, 3, 4, 5],
'subdict': {'first': 1, 'second': 2, 'third': 3}}
Есть АКСОН (текстовый) формат, объединяющий лучший JSON, XML и YAML.Формат AXON вполне читаем и относительно компактен.
Модуль Python (2.7/3.3-3.7) пиаксон поддерживает load(s)
/dump(s)
функциональность, включая итеративную loading
/dumping
.Это достаточно быстро, чтобы быть полезным.
Рассмотрим простой пример:
>>> d = {
'age': 27, 'name': 'Joe',
'numbers': [1, 2, 3, 4, 5],
'subdict': {'first': 1, 'second': 2, 'third': 3}
}
# pretty form
>>> axon.dumps(d, pretty=1)
{ age: 27
name: "Joe"
numbers: [1 2 3 4 5]
subdict: {
first: 1
second: 2
third: 3}}
# compact form
>>> axon.dumps(d)
{age:27 name:"Joe" numbers:[1 2 3 4 5] subdict:{first:1 second:2 third:3}}
Он также может обрабатывать несколько объектов в сообщении:
>>> msg = axon.dumps([{'a':1, 'b':2, 'c':3}, {'a':2, 'b':3, 'c':4}])
>>> print(msg)
{a:1 b:2 c:3}
{a:2 b:3 c:4}
{a:3 b:4 c:5}
а затем загрузите их итеративно:
for d in axon.iloads(msg):
print(d)