Pregunta

Necesito almacenar estructuras Python hechas de listas / diccionarios, tuplas en un formato legible por humanos. La idea es como usar algo similar a pickle , pero pickle no es amigable para los humanos. Otras opciones que me vienen a la mente son YAML (a través de PyYAML y JSON (a través de simplejson ) serializadores.

¿Alguna otra opción que se te ocurra?

Gracias de antemano.

¿Fue útil?

Solución

Para casos simples, pprint () y eval () vienen a la mente.

Usando su ejemplo:

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

Me lo pensaría dos veces antes de arreglar dos requisitos con la misma herramienta. ¿Ha considerado usar pickle para la serialización y luego pprint () (o un visor de objetos más elegante) para los humanos que miran los objetos?

Otros consejos

Si es solo lista de Python, diccionario y objeto de tupla. - JSON es el camino a seguir. Es legible para los humanos, muy fácil de manejar e independiente del lenguaje.

Precaución: las tuplas se convertirán en listas en simplejson.

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

Si busca más representaciones de las que JSON cubre, le recomiendo que revise PyON (notación de objetos de Python) ... aunque creo que está restringido a 2.6 / 3.0 y superior, ya que se basa en el módulo ast . Maneja instancias de clases personalizadas y tipos de datos recursivos, entre otras características, que es más de lo que proporciona JSON.

Debería revisar jsonpickle ( https://github.com/jsonpickle/jsonpickle ). Escribirá cualquier objeto python en un archivo json. Luego puedes leer ese archivo de nuevo en un objeto python. Lo bueno es que el archivo intermedio es muy legible porque es json.

¿Qué quieres decir con que esto no es legible para humanos? ;)

>>> 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."

Ok, bueno, tal vez solo requiera algo de práctica & # 8230; o podrías hacer trampa ...

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

Aún tendría que leer el objeto encurtido de un archivo, sin embargo, no tendría que cargar . Entonces, si es un " peligroso " objeto, aún puede ser capaz de averiguarlo antes de hacer load . Si estás atascado con un pickle , podría ser una buena opción para descifrar lo que tienes.

Para usar simplejson primero 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)

da como resultado que json sea:

{"age": 27, "subdict": {"second": 2, "third": 3, "first": 1}, "name": "Joe", "numbers": [1, 2, 3, 4, 5]}

Observe que apenas cambia el formato del diccionario, pero debe ejecutar este paso para garantizar que los datos JSON sean válidos.

Puedes seguir imprimiendo el resultado:

import pprint
pprint.pprint(my_structure)

resultados en:

{'age': 27,
 'name': 'Joe',
 'numbers': [1, 2, 3, 4, 5],
 'subdict': {'first': 1, 'second': 2, 'third': 3}}

Hay un formato AXON (textual) que combina el mejor de JSON, XML y YAML. El formato AXON es bastante legible y relativamente compacto.

El módulo python (2.7 / 3.3-3.7) pyaxon admite la carga de ( s) / volcado (s) , incluida la carga iterativa de / dumping . Es lo suficientemente rápido para ser útil.

Considere el ejemplo simple:

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

También puede manejar múltiples objetos en el mensaje:

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

y luego cárgalos iterativamente:

for d in axon.iloads(msg):
   print(d)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top