Buscar..


Observaciones

Para obtener la documentación completa, incluida la funcionalidad específica de la versión, consulte la documentación oficial .

Los tipos

Valores predeterminados

El módulo json manejará la codificación y decodificación de los siguientes tipos de manera predeterminada:

Tipos de serialización:

JSON Pitón
objeto dictado
formación lista
cuerda str
número (int) En t
numero (real) flotador
verdadero Falso Verdadero Falso
nulo Ninguna

El módulo json también entiende NaN , Infinity e -Infinity como sus valores flotantes correspondientes, que están fuera de la especificación JSON.

Tipos de serialización:

Pitón JSON
dictado objeto
lista, tupla formación
str cuerda
Enums, float, (int / float) -derived número
Cierto cierto
Falso falso
Ninguna nulo

Para no permitir la codificación de NaN , Infinity e -Infinity , debe codificar con allow_nan=False . Esto generará un ValueError si intenta codificar estos valores.

Personalización (des) serialización

Existen varios enlaces que le permiten manejar datos que deben representarse de manera diferente. El uso de functools.partial permite aplicar parcialmente los parámetros relevantes a estas funciones para su comodidad.

Publicación por entregas:

Puede proporcionar una función que opere en objetos antes de que se serialicen así:

# my_json module

import json
from functools import partial

def serialise_object(obj):
    # Do something to produce json-serialisable data
    return dict_obj

dump = partial(json.dump, default=serialise_object)
dumps = partial(json.dumps, default=serialise_object)

De serialización:

Hay varios enlaces que son manejados por las funciones json, como object_hook y parse_float. Para obtener una lista exhaustiva de su versión de python, consulte aquí .

# my_json module

import json
from functools import partial

def deserialise_object(dict_obj):
    # Do something custom
    return obj

def deserialise_float(str_obj):
    # Do something custom
    return obj

load = partial(json.load, object_hook=deserialise_object, parse_float=deserialise_float)
loads = partial(json.loads, object_hook=deserialise_object, parse_float=deserialise_float)

Mayor (des) serialización personalizada:

El módulo json también permite la extensión / sustitución de json.JSONEncoder y json.JSONDecoder para manejar varios tipos. Los ganchos documentados anteriormente se pueden agregar como valores predeterminados creando un método de nombre equivalente. Para usarlos, simplemente pase la clase como el parámetro cls a la función relevante. El uso de functools.partial permite aplicar parcialmente el parámetro cls a estas funciones por conveniencia, por ejemplo,

# my_json module

import json
from functools import partial

class MyEncoder(json.JSONEncoder):
    # Do something custom

class MyDecoder(json.JSONDecoder):
    # Do something custom

dump = partial(json.dump, cls=MyEncoder)
dumps = partial(json.dumps, cls=MyEncoder)
load = partial(json.load, cls=MyDecoder)
loads = partial(json.loads, cls=MyDecoder)

Creando JSON desde el dictado de Python

import json
d = {
    'foo': 'bar',
    'alice': 1,
    'wonderland': [1, 2, 3]
}
json.dumps(d)

El fragmento de código anterior devolverá lo siguiente:

'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'

Creando el dictado de Python desde JSON

import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)

El fragmento de código anterior devolverá lo siguiente:

{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}

Almacenamiento de datos en un archivo

El siguiente fragmento de código codifica los datos almacenados en d en JSON y los almacena en un archivo (reemplace el filename con el nombre real del archivo).

import json

d = {
    'foo': 'bar',
    'alice': 1,
    'wonderland': [1, 2, 3]
}

with open(filename, 'w') as f:
    json.dump(d, f)

Recuperando datos de un archivo

El siguiente fragmento de código abre un archivo codificado JSON (reemplaza el filename con el nombre real del archivo) y devuelve el objeto que está almacenado en el archivo.

import json

with open(filename, 'r') as f:
    d = json.load(f)

`load` vs` loads`, `dump` vs` dumps`

El módulo json contiene funciones para leer y escribir en y desde cadenas de Unicode, y para leer y escribir en y desde archivos. Estos se diferencian por una s final en el nombre de la función. En estos ejemplos, usamos un objeto StringIO, pero las mismas funciones se aplicarían a cualquier objeto similar a un archivo.

Aquí usamos las funciones basadas en cadenas:

import json

data = {u"foo": u"bar", u"baz": []}
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}'
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}

Y aquí usamos las funciones basadas en archivos:

import json

from io import StringIO

json_file = StringIO()
data = {u"foo": u"bar", u"baz": []}
json.dump(data, json_file)
json_file.seek(0)  # Seek back to the start of the file before reading
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0)  # Seek back to the start of the file before reading
json.load(json_file)
# {u"foo": u"bar", u"baz": []}

Como puede ver, la principal diferencia es que al descargar datos json debe pasar el identificador de archivo a la función, en lugar de capturar el valor de retorno. También vale la pena señalar que debe buscar el inicio del archivo antes de leer o escribir, para evitar la corrupción de datos. Al abrir un archivo, el cursor se coloca en la posición 0 , por lo que lo siguiente también funcionaría:

import json

json_file_path = './data.json'
data = {u"foo": u"bar", u"baz": []}

with open(json_file_path, 'w') as json_file:
    json.dump(data, json_file)

with open(json_file_path) as json_file:
    json_file_content = json_file.read()
    # u'{"foo": "bar", "baz": []}'

with open(json_file_path) as json_file:
    json.load(json_file)
    # {u"foo": u"bar", u"baz": []}

Tener las dos formas de tratar con los datos json le permite trabajar de manera idiomática y eficiente con los formatos que se basan en json, como json-per-line de pyspark :

# loading from a file
data = [json.loads(line) for line in open(file_path).splitlines()]

# dumping to a file
with open(file_path, 'w') as json_file:
    for item in data:
        json.dump(item, json_file)
        json_file.write('\n')

Llamando a `json.tool` desde la línea de comandos a la salida JSON de impresión bonita

Dado un archivo JSON "foo.json" como:

{"foo": {"bar": {"baz": 1}}}

podemos llamar al módulo directamente desde la línea de comando (pasando el nombre del archivo como un argumento) para imprimirlo en forma bonita:

$ python -m json.tool foo.json
{
    "foo": {
        "bar": {
            "baz": 1
        }
    }
}

El módulo también recibirá información de STDOUT, por lo que (en Bash) también podríamos hacer:

$ cat foo.json | python -m json.tool

Formato de salida JSON

Digamos que tenemos los siguientes datos:

>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

Simplemente descartando esto como JSON no hace nada especial aquí:

>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

Configuración de sangría para obtener una salida más bonita

Si queremos una impresión bonita, podemos establecer un tamaño de indent :

>>> print(json.dumps(data, indent=2))
{
  "cats": [
    {
      "name": "Tubbs",
      "color": "white"
    },
    {
      "name": "Pepper",
      "color": "black"
    }
  ]
}

Ordenando las teclas alfabéticamente para obtener un resultado consistente

Por defecto, el orden de las teclas en la salida no está definido. Podemos obtenerlos en orden alfabético para asegurarnos de que siempre obtengamos la misma salida:

>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}

Deshacerse de los espacios en blanco para obtener una salida compacta

Podríamos querer deshacernos de los espacios innecesarios, lo que se hace configurando cadenas separadoras diferentes de las predeterminadas ', ' y ': ' :

>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}

JSON que codifica objetos personalizados

Si solo intentamos lo siguiente:

import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)}
print(json.dumps(data))

recibimos un error que dice que TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable .

Para poder serializar correctamente el objeto de fecha y hora, necesitamos escribir un código personalizado sobre cómo convertirlo:

class DatetimeJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        try:
            return obj.isoformat()
        except AttributeError:
            # obj has no isoformat method; let the builtin JSON encoder handle it
            return super(DatetimeJSONEncoder, self).default(obj)

y luego use esta clase de codificador en lugar de json.dumps :

encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow