Szukaj…


Uwagi

Pełna dokumentacja, w tym funkcje specyficzne dla wersji, znajduje się w oficjalnej dokumentacji .

Rodzaje

Domyślne

moduł json domyślnie obsługuje kodowanie i dekodowanie poniższych typów:

Typy usuwania serializacji:

JSON Pyton
obiekt dyktować
szyk lista
strunowy str
liczba (int) int
liczba (rzeczywista) pływak
prawda fałsz Prawda fałsz
zero Żaden

Moduł json również rozumie NaN , Infinity i -Infinity jako odpowiadające im wartości zmiennoprzecinkowe, które są poza specyfikacją JSON.

Typy serializacji:

Pyton JSON
dyktować obiekt
lista, krotka szyk
str strunowy
int, float, (int / float) wyprowadzone Enums numer
Prawdziwe prawdziwe
Fałszywy fałszywy
Żaden zero

Aby zabronić kodowania NaN , Infinity i -Infinity , musisz zakodować za pomocą allow_nan=False . Spowoduje to podniesienie ValueError jeśli spróbujesz zakodować te wartości.

Niestandardowa (de-) serializacja

Istnieją różne haki, które pozwalają przetwarzać dane, które muszą być reprezentowane w różny sposób. Zastosowanie functools.partial pozwala częściowo zastosować odpowiednie parametry do tych funkcji dla wygody.

Serializacja:

Możesz podać funkcję, która działa na obiektach przed ich serializacją w następujący sposób:

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

Dezeralizacja:

Istnieją różne haki obsługiwane przez funkcje json, takie jak object_hook i parse_float. Wyczerpująca lista twojej wersji Pythona znajduje się tutaj .

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

Dalsza niestandardowa (de-) serializacja:

Moduł json pozwala również na rozszerzenie / podstawienie json.JSONEncoder i json.JSONDecoder do obsługi różnych typów. Haki udokumentowane powyżej można dodać jako domyślne, tworząc metodę o równoważnej nazwie. Aby ich użyć, wystarczy przekazać klasę jako parametr cls do odpowiedniej funkcji. Zastosowanie functools.partial pozwala częściowo zastosować parametr cls do tych funkcji dla wygody, np

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

Tworzenie JSON z Python Dict

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

Powyższy fragment kodu zwróci następujące informacje:

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

Tworzenie słownika Python z JSON

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

Powyższy fragment kodu zwróci następujące informacje:

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

Przechowywanie danych w pliku

Poniższy fragment kodu koduje dane zapisane w d do JSON i zapisuje je w pliku (zamień filename na rzeczywistą nazwę pliku).

import json

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

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

Pobieranie danych z pliku

Poniższy fragment kodu otwiera plik zakodowany w JSON (zamień filename na rzeczywistą nazwę pliku) i zwraca obiekt przechowywany w pliku.

import json

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

„ładuj” vs „ładunki”, „zrzut” vs „zrzuty”

Moduł json zawiera funkcje zarówno do odczytu i zapisu do i z ciągów znaków Unicode oraz do odczytu i zapisu do i z plików. Różnią się one znakiem końcowym s w nazwie funkcji. W tych przykładach używamy obiektu StringIO, ale te same funkcje miałyby zastosowanie do każdego obiektu podobnego do pliku.

Tutaj używamy funkcji opartych na łańcuchach:

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

I tutaj korzystamy z funkcji opartych na plikach:

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

Jak widać, główna różnica polega na tym, że podczas zrzutu danych JSON należy przekazać uchwyt pliku do funkcji, w przeciwieństwie do przechwytywania wartości zwracanej. Warto również zauważyć, że należy szukać początku pliku przed odczytem lub zapisem, aby uniknąć uszkodzenia danych. Podczas otwierania pliku kursor jest umieszczany w pozycji 0 , więc działałoby również:

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

Oba sposoby postępowania z danymi json pozwalają na idiomatyczną i wydajną pracę z formatami pyspark na json, takimi jak json-per-line w 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')

Wywołanie `json.tool` z wiersza poleceń w celu wydrukowania ładnego wyniku JSON

Biorąc pod uwagę plik JSON „foo.json”, taki jak:

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

możemy wywołać moduł bezpośrednio z linii poleceń (przekazując nazwę pliku jako argument), aby go ładnie wydrukować:

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

Moduł pobierze również dane wejściowe z STDOUT, więc (w Bash) możemy równie dobrze zrobić:

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

Formatowanie wyjścia JSON

Powiedzmy, że mamy następujące dane:

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

Po prostu zrzucam to, ponieważ JSON nie robi tutaj nic specjalnego:

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

Ustawienie wcięcia, aby uzyskać ładniejszy wynik

Jeśli chcemy ładnego drukowania, możemy ustawić indent :

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

Sortuj klucze alfabetycznie, aby uzyskać spójny wynik

Domyślnie kolejność kluczy w danych wyjściowych jest niezdefiniowana. Możemy uzyskać je w kolejności alfabetycznej, aby mieć pewność, że zawsze otrzymamy ten sam wynik:

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

Pozbycie się białych znaków, aby uzyskać kompaktowe wyjście

Możemy chcieć pozbyć się niepotrzebnych spacji, co odbywa się poprzez ustawienie ciągów separatora innych niż domyślne ', ' i ': ' :

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

Kodowanie niestandardowych obiektów JSON

Jeśli po prostu spróbujemy:

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

TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable się błąd informujący, że TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable .

Aby móc poprawnie serializować obiekt datetime, musimy napisać niestandardowy kod, aby go przekonwertować:

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)

a następnie użyj tej klasy kodera zamiast 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow