Ricerca…


Osservazioni

Per la documentazione completa inclusa la funzionalità specifica della versione, consultare la documentazione ufficiale .

tipi

Defaults

il modulo json gestirà la codifica e la decodifica dei seguenti tipi di default:

Tipi di serializzazione:

JSON Pitone
oggetto dict
schieramento elenco
stringa str
numero (int) int
numero (reale) galleggiante
vero falso Vero falso
nullo Nessuna

Il modulo json comprende anche NaN , Infinity e -Infinity come valori float corrispondenti, che è al di fuori della specifica JSON.

Tipi di serializzazione:

Pitone JSON
dict oggetto
lista, tupla schieramento
str stringa
int, float, (int / float) -derived Enums numero
Vero vero
falso falso
Nessuna nullo

Per disabilitare la codifica di NaN , Infinity e -Infinity devi codificare con allow_nan=False . Ciò solleverà ValueError se ValueError di codificare questi valori.

Serializzazione personalizzata (de-)

Esistono vari hook che consentono di gestire i dati che devono essere rappresentati in modo diverso. L'uso di functools.partial consente di applicare parzialmente i parametri rilevanti a queste funzioni per comodità.

serializzazione:

È possibile fornire una funzione che opera sugli oggetti prima di essere serializzati in questo modo:

# 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-serializzazione:

Ci sono vari hook che sono gestiti dalle funzioni JSON, come object_hook e parse_float. Per un elenco completo per la tua versione di Python, vedi qui .

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

Ulteriori personalizzazioni (de-) serializzazione:

Il modulo json consente anche l'estensione / sostituzione di json.JSONEncoder e json.JSONDecoder per gestire vari tipi. Gli hook documentati sopra possono essere aggiunti come predefiniti creando un metodo con un nome equivalente. Per utilizzarli basta passare la classe come parametro cls alla funzione rilevante. L'uso di functools.partial consente di applicare parzialmente il parametro cls a queste funzioni per comodità, ad es

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

Creazione di JSON da Python dict

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

Lo snippet riportato sopra restituirà quanto segue:

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

Creazione di Dict Python da JSON

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

Lo snippet riportato sopra restituirà quanto segue:

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

Memorizzazione di dati in un file

Il seguente frammento codifica i dati memorizzati in d in JSON e li archivia in un file (sostituisce il filename con il nome effettivo del file).

import json

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

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

Recupero di dati da un file

Lo snippet seguente apre un file con codifica JSON (sostituisce il filename con il nome effettivo del file) e restituisce l'oggetto che è archiviato nel file.

import json

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

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

Il modulo json contiene funzioni sia per la lettura e la scrittura da e verso le stringhe Unicode, sia per la lettura e la scrittura da e verso i file. Questi sono differenziati da un trailing s nel nome della funzione. In questi esempi utilizziamo un oggetto StringIO, ma le stesse funzioni si applicherebbero a qualsiasi oggetto simile a un file.

Qui usiamo le funzioni basate su stringhe:

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": []}

E qui usiamo le funzioni basate su file:

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": []}

Come puoi vedere, la differenza principale è che quando si scaricano dati json è necessario passare l'handle del file alla funzione, invece di acquisire il valore restituito. Vale anche la pena notare che è necessario cercare all'inizio del file prima di leggere o scrivere, al fine di evitare la corruzione dei dati. Quando si apre un file, il cursore si trova nella posizione 0 , quindi anche il seguente funzionerà:

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": []}

Avere entrambi i modi di gestire i dati json consente di lavorare in modo idiomatico ed efficiente con i formati basati su json, come ad esempio json-per-line di 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')

Chiamando `json.tool` dalla riga di comando all'output JSON pretty-print

Dato un file JSON "foo.json" come:

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

possiamo chiamare il modulo direttamente dalla riga di comando (passando il nome del file come argomento) per stamparlo in modo carino:

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

Il modulo prenderà anche input da STDOUT, quindi (in Bash) potremmo fare altrettanto:

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

Formattazione dell'output JSON

Diciamo che abbiamo i seguenti dati:

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

Basta scaricare questo come JSON non fa nulla di speciale qui:

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

Impostazione dell'indentazione per ottenere risultati migliori

Se vogliamo una bella stampa, possiamo impostare una dimensione del indent :

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

Ordinamento dei tasti alfabeticamente per ottenere risultati coerenti

Per impostazione predefinita, l'ordine delle chiavi nell'output non è definito. Possiamo ottenerli in ordine alfabetico per assicurarci di ottenere sempre lo stesso risultato:

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

Liberarsi degli spazi bianchi per ottenere risultati compatti

Potremmo desiderare di eliminare gli spazi non necessari, operazione che viene eseguita impostando le stringhe di separazione diverse da ', ' e ': ' predefiniti:

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

JSON che codifica oggetti personalizzati

Se solo proviamo il seguente:

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

viene visualizzato un errore che dice TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable .

Per poter serializzare correttamente l'oggetto datetime, è necessario scrivere codice personalizzato per come 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)

e quindi utilizzare questa classe di encoder invece di 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow