Sök…


Anmärkningar

Kontrollera den officiella dokumentationen för full dokumentation inklusive versionspecifik funktionalitet.

typer

defaults

json modulen hanterar kodning och avkodning av nedanstående typer som standard:

Avserialiseringstyper:

JSON Pytonorm
objekt dict
array lista
sträng str
nummer (int) int
nummer (verkligt) flyta
sant falskt Sant falskt
null Ingen

json modulen förstår också NaN , Infinity och -Infinity som deras motsvarande flottörvärden, som ligger utanför JSON-specifikationen.

Serialiseringstyper:

Pytonorm JSON
dict objekt
lista, tupel array
str sträng
int, float, (int / float) -ledda Enums siffra
Sann Sann
Falsk falsk
Ingen null

För att tillåta kodning av NaN , Infinity och- -Infinity måste du koda med allow_nan=False . Detta höjer sedan en ValueError om du försöker att koda dessa värden.

Anpassad (de-) serialisering

Det finns olika krokar som gör att du kan hantera data som måste representeras annorlunda. Användning av functools.partial låter dig delvis tillämpa relevanta parametrar på dessa funktioner för bekvämlighet.

Serialization:

Du kan tillhandahålla en funktion som fungerar på objekt innan de seriellt görs så:

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

Det finns olika krokar som hanteras av json-funktionerna, till exempel object_hook och parse_float. För en uttömmande lista för din version av python, se här .

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

Ytterligare anpassad (de-) serialisering:

json modulen tillåter också förlängning / utbyte av json.JSONEncoder och json.JSONDecoder att hantera diverse typer. Krokarna som dokumenterats ovan kan läggas till som standard genom att skapa en likvärdigt benämnd metod. För att använda dessa, skicka bara klassen som cls parameter till relevant funktion. Användning av functools.partial låter dig delvis tillämpa cls-parametern på dessa funktioner för bekvämlighet, t.ex.

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

Skapa JSON från Python dict

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

Ovanstående kod kommer att returnera följande:

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

Skapa Python dict från JSON

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

Ovanstående kod kommer att returnera följande:

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

Lagring av data i en fil

Följande kod kodar data lagrade i d i JSON och lagrar dem i en fil (ersätt filename med filens faktiska namn).

import json

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

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

Hämtar data från en fil

Följande kodavsnitt öppnar en JSON-kodad fil (ersätt filename med filens verkliga namn) och returnerar objektet som är lagrat i filen.

import json

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

`last` vs` loads`, `dump` vs` dumps`

json modulen innehåller funktioner för både läsning och skrivning till och från unicode-strängar, och läsning och skrivning till och från filer. Dessa skiljer sig genom en avslutande s i funktionsnamnet. I dessa exempel använder vi ett StringIO-objekt, men samma funktioner skulle gälla för alla filliknande objekt.

Här använder vi de strängbaserade funktionerna:

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

Och här använder vi de filbaserade funktionerna:

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

Som du kan se är huvudskillnaden att när du dumpar json-data måste du skicka filhandtaget till funktionen, i motsats till att fånga returvärdet. Det är också värt att notera att du måste försöka börja filen innan du läser eller skriver för att undvika datakorruption. När du öppnar en fil placeras markören på position 0 , så nedan fungerar också:

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

Genom att ha båda sätten att hantera json-data kan du idiomatiskt och effektivt arbeta med format som bygger på json, till exempel pyspark 's json-per-line:

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

Ringa `json.tool` från kommandoraden för att skriva ut JSON-utgången

Får en del JSON-fil "foo.json" som:

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

vi kan ringa modulen direkt från kommandoraden (passera filnamnet som ett argument) för att skriva ut den:

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

Modulen tar också input från STDOUT, så (i Bash) kan vi lika göra:

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

Formatera JSON-utgången

Låt oss säga att vi har följande data:

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

Bara dumpa detta eftersom JSON inte gör något speciellt här:

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

Ställer in intryck för att få snyggare utdata

Om vi vill ha bra utskrift kan vi ställa in en indent :

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

Sortera tangenter alfabetiskt för att få konsekvent utdata

Som standard är knapparnas ordning inte definierad. Vi kan få dem i alfabetisk ordning för att se till att vi alltid får samma output:

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

Bli av med utrymme för att få kompakt utgång

Vi kanske vill bli av med onödiga utrymmen, vilket görs genom att ställa in separatorsträngar som skiljer sig från standard ', ' och ': ' :

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

JSON som kodar anpassade objekt

Om vi bara försöker följande:

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

vi får ett fel med att säga TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable .

För att kunna serialisera datetime-objektet ordentligt måste vi skriva anpassad kod för hur man konverterar det:

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)

och använd sedan denna kodare i stället för 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow