Подтвердить что ты не робот

Сериализация понятных пользователем Python объектов

Мне нужно хранить структуры Python из списков/словарей, кортежи в читаемый человеком формат. Идея похожа на использование чего-то похожего на pickle, но рассол не дружелюбен для человека. Другие варианты, которые мне приходят, YAML (через PyYAML и JSON (через simplejson) сериализаторы.

Любой другой вариант, который приходит вам на ум?

Спасибо заранее.

4b9b3361

Ответ 1

Для простых случаев приходят на ум 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() (или более привлекательного зрителя объектов) для людей, смотрящих на объекты?

Ответ 2

Если это только список Python, словарь и кортеж. - JSON - это путь. Его читаемость на людях, очень простая в обращении и независимая от языка.

Внимание: кортежи будут преобразованы в списки в simplejson.

In [109]: simplejson.loads(simplejson.dumps({'d':(12,3,4,4,5)}))
Out[109]: {u'd': [12, 3, 4, 4, 5]}

Ответ 3

Если вы больше других представлений, чем описано в JSON, я настоятельно рекомендую проверить PyON (Python Object Notation)... Хотя я считаю, что он ограничен 2.6/3.0 и выше, поскольку он полагается на модуль ast. Он обрабатывает экземпляры специальных экземпляров и рекурсивные типы данных, среди других функций, что больше, чем обеспечивается JSON.

Ответ 4

Вы должны проверить jsonpickle (http://code.google.com/p/jsonpickle/). Он выведет любой объект python в json файл. Затем вы можете прочитать этот файл обратно в объект python. Приятно, что файл inbetween очень читаем, потому что он json.

Ответ 5

Что вы имеете в виду, это не читается человеком?;)

>>> 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, это может быть хорошим вариантом для расшифровки того, что у вас есть.

Ответ 6

Чтобы использовать simplejson сначала easy_install simplejson:

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}}

Ответ 7

Существует AXON (текстовый) формат, который объединяет лучший JSON, XML и YAML. Формат AXON довольно читабельен и относительно компактен.

Модуль python (2.7/3.3/3.4) pyaxon поддерживает функциональность 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)