2. JSON Serialization

2.1. JSON syntax

Format JSON jest podobny do zapisu dict w Python, ale różni się:

  • nie może być przecinka po ostatnim elemencie list

  • zawsze stosowany jest podwójny cudzysłów

  • true i false jest pisane małymi literami

  • zamiast None jest null

  • konwencją jest stosowanie camelCase a nie snake_case, ale oba są poprawne

2.1.1. Example

[
    {"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": 4.9, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": false, "sepalWidth": true, "petalLength": null, "petalWidth": 0.2, "species": null}
]

2.2. JSON Serialization of simple objects

  • json.dump(DATA, file)

  • json.dumps(DATA)

  • json.load(DATA, file)

  • json.loads(DATA)

2.2.1. Serialize to JSON

Listing 2.18. Serializing to JSON
import json


DATA = {
    'first_name': 'Jan',
    'last_name': 'Twardowski'
}

output = json.dumps(DATA)
print(output)
# '{"first_name": "Jan", "last_name": "Twardowski"}'

2.2.2. Deserialize from JSON

Listing 2.19. Deserialize from JSON
import json


DATA = '{"first_name": "Jan", "last_name": "Twardowski"}'

output = json.loads(DATA)
print(output)
# {
#     'first_name': 'Jan',
#     'last_name': 'Twardowski'
# }

2.3. Serializing datetime and date

2.3.1. Encoding datetime and date

  • Encoder will be used, when standard procedure fails

Listing 2.20. Exception during encoding datetime
from datetime import datetime, date
import json


DATA = {
    'name': 'Pan Twardowski',
    'date': date(1961, 4, 12),
    'datetime': datetime(1969, 7, 21, 14, 56, 15),
}

output = json.dumps(DATA)
# TypeError: Object of type date is not JSON serializable
Listing 2.21. Encoding datetime and date
from datetime import datetime, date
import json


DATA = {
    'name': 'Pan Twardowski',
    'date': date(1961, 4, 12),
    'datetime': datetime(1969, 7, 21, 14, 56, 15),
}


class JSONDatetimeEncoder(json.JSONEncoder):
    def default(self, value):

        if isinstance(value, datetime):
            return value.strftime('%Y-%m-%dT%H:%M:%S.%fZ')
        elif isinstance(value, date):
            return value.strftime('%Y-%m-%d')


output = json.dumps(DATA, cls=JSONDatetimeEncoder)
print(output)
# '{"name": "Pan Twardowski", "date": "1961-04-12", "datetime": "1969-07-21T14:56:15.000Z"}'

2.3.2. Decoding datetime and date

Listing 2.22. Simple loading returns str not datetime or date
import json


DATA = '{"name": "Pan Twardowski", "date": "1961-04-12", "datetime": "1969-07-21T14:56:15.000Z"}'

output = json.loads(DATA)
print(output)
# {
#     'name': 'Pan Twardowski',
#     'date': '1961-04-12',
#     'datetime': '1969-07-21T14:56:15.000Z',
# }
Listing 2.23. Decoding datetime and date
from datetime import datetime, timezone
import json


DATA = '{"name": "Pan Twardowski", "date": "1961-04-12", "datetime": "1969-07-21T14:56:15.000Z"}'


class JSONDatetimeDecoder(json.JSONDecoder):
    def __init__(self):
        super().__init__(object_hook=self.default)

    def default(self, obj):
        for key, value in obj.items():

            if key == 'datetime':
                dt = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%fZ')
                obj['datetime'] = dt.replace(tzinfo=timezone.utc)

            elif key == 'date':
                dt = datetime.strptime(value, '%Y-%m-%d')
                obj['date'] = dt.replace(tzinfo=timezone.utc).date()

        return obj


output = json.loads(DATA, cls=JSONDatetimeDecoder)
print(output)
# {
#     'name': 'Pan Twardowski',
#     'date': date(1961, 4, 12),
#     'datetime': datetime(1969, 7, 21, 14, 56, 15, tzinfo=datetime.timezone.utc),
# }

2.4. Serializing objects

2.4.1. Encoding objects

  • Encoder will be used, when standard procedure fails

Listing 2.24. Encoding objects to JSON
import json


class Address:
    def __init__(self, city, state):
        self.city = city
        self.state = state


class Contact:
    def __init__(self, name, addresses=()):
        self.name = name
        self.addresses = addresses


DATA = [
    Contact(name='Jan Twardowski', addresses=(
        Address(city='Houston', state='Texas'),
        Address(city='Kennedy Space Center', state='Florida'),
        Address(city='Pasadena', state='California'),
        Address(city='Palmdale', state='California'),
    )),
    Contact(name='Mark Watney'),
    Contact(name='José Jiménez', addresses=()),
]


class JSONObjectEncoder(json.JSONEncoder):
    def default(self, obj):
        result = obj.__dict__
        result['__type__'] = obj.__class__.__name__
        return result


output = json.dumps(DATA, cls=JSONObjectEncoder)

print(output)
# [
#    {"__type__":"Contact", "name":"Jan Twardowski", "addresses":[
#          {"__type__":"Address", "city":"Houston", "state":"Texas"},
#          {"__type__":"Address", "city":"Kennedy Space Center", "state":"Florida"},
#          {"__type__":"Address", "city":"Pasadena", "state":"California"},
#          {"__type__":"Address", "city":"Palmdale", "state":"California"}]},
#    {"__type__":"Contact", "name":"Mark Watney", "addresses":[]},
#    {"__type__":"Contact", "name":"Jos\u00e9 Jim\u00e9nez", "addresses":[]}
# ]

2.4.2. Decoding objects

Listing 2.25. Decoding objects from JSON
import json
import sys


DATA = """
[
    {"__type__":"Contact", "name":"Jan Twardowski", "addresses":[
         {"__type__":"Address", "city":"Houston", "state":"Texas"},
         {"__type__":"Address", "city":"Kennedy Space Center", "state":"Florida"},
         {"__type__":"Address", "city":"Pasadena", "state":"California"},
         {"__type__":"Address", "city":"Palmdale", "state":"California"}]},
   {"__type__":"Contact", "name":"Mark Watney", "addresses":[]},
   {"__type__":"Contact", "name":"Jos\u00e9 Jim\u00e9nez", "addresses":[]}
]
"""


class Address:
    def __init__(self, city, state):
        self.city = city
        self.state = state


class Contact:
    def __init__(self, name, addresses=()):
        self.name = name
        self.addresses = addresses


class JSONObjectDecoder(json.JSONDecoder):
    def __init__(self):
        super().__init__(object_hook=self.default)

    def default(self, obj):
        type = obj.pop('__type__')
        cls = getattr(sys.modules[__name__], type)
        return cls(**obj)


output = json.loads(DATA, cls=JSONObjectDecoder)
print(output)
# [
#     Contact(name='Jan Twardowski', addresses=(
#         Address(city='Houston', state='Texas'),
#         Address(city='Kennedy Space Center', state='Florida'),
#         Address(city='Pasadena', state='California'),
#         Address(city='Palmdale', state='California'),
#     )),
#     Contact(name='Mark Watney'),
#     Contact(name='José Jiménez', addresses=()),
# ]

2.5. Pretty Printing JSON

2.5.1. JSON can be compressed

  • It is not very readable

$ URL='https://raw.githubusercontent.com/AstroMatt/book-python/master/serialization/data/iris.json'
$ curl $URL

[{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.7,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":2.9,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":7,"sepalWidth":3.2,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.3,"petalLength":4,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.5,"sepalWidth":2.8,"petalLength":4.6,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.5,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":4.7,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":4.9,"sepalWidth":2.4,"petalLength":3.3,"petalWidth":1,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":2.9,"petalLength":4.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.2,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":6,"petalWidth":2.5,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.1,"sepalWidth":3,"petalLength":5.9,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.9,"petalLength":5.6,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3,"petalLength":5.8,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.6,"sepalWidth":3,"petalLength":6.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":4.9,"sepalWidth":2.5,"petalLength":4.5,"petalWidth":1.7,"species":"virginica"},{"sepalLength":7.3,"sepalWidth":2.9,"petalLength":6.3,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":2.5,"petalLength":5.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.6,"petalLength":6.1,"petalWidth":2.5,"species":"virginica"}]

2.5.2. Pretty Printing JSON

$ URL='https://raw.githubusercontent.com/AstroMatt/book-python/master/serialization/data/iris.json'
$ curl $URL |python -m json.tool
[
    {
        "petalLength": 1.4,
        "petalWidth": 0.2,
        "sepalLength": 5.1,
        "sepalWidth": 3.5,
        "species": "setosa"
    },
    {
        "petalLength": 1.4,
        "petalWidth": 0.2,
        "sepalLength": 4.9,
        "sepalWidth": 3,
        "species": "setosa"
    },
    {
        "petalLength": 1.3,
        "petalWidth": 0.2,
        "sepalLength": 4.7,
        "sepalWidth": 3.2,
        "species": "setosa"
    },
...

2.5.3. Check JSON Syntax

$ echo '{"sepalLength":5.1,"sepalWidth":3.5,}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 37 (char 36)

2.6. Assignments

2.6.1. Iris Serialize

  • Filename: json_iris_serialize.py

  • Lines of code to write: 8 lines

  • Estimated time of completion: 20 min

  • Input data: Listing 2.26.

Listing 2.26. Iris Serialize
DATA = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica'),
    (7.1, 3.0, 5.9, 2.1, 'virginica'),
    (4.6, 3.4, 1.4, 0.3, 'setosa'),
    (5.4, 3.9, 1.7, 0.4, 'setosa'),
    (5.7, 2.8, 4.5, 1.3, 'versicolor'),
    (5.0, 3.6, 1.4, 0.3, 'setosa'),
    (5.5, 2.3, 4.0, 1.3, 'versicolor'),
    (6.5, 3.0, 5.8, 2.2, 'virginica'),
    (6.5, 2.8, 4.6, 1.5, 'versicolor'),
    (6.3, 3.3, 6.0, 2.5, 'virginica'),
    (6.9, 3.1, 4.9, 1.5, 'versicolor'),
    (4.6, 3.1, 1.5, 0.2, 'setosa'),
]
  1. Z danych wydziel nagłówek i pomiary

  2. Wygeneruj List[dict]

    • klucz: nazwa z nagłówka

    • wartość: wyniki pomiarów lub gatunek

  3. Słownik wynikowy ma wyglądać następująco:

    [
        {'Sepal length': 5.8, 'Sepal width': 2.7, ...},
        {'Sepal length': 5.1, 'Sepal width': 3.5, ...},
        {'Sepal length': 5.7, 'Sepal width': 2.8, ...},
        ...
    ]
    
  4. Zapisz do pliku iris.json w formacie JSON

The whys and wherefores
  • Serializacja danych

  • Korzystanie z biblioteki JSON

  • Konwersja typów

  • Praca z plikami

2.6.2. Iris deserialize

  • Filename: json_iris_deserialize.py

  • Lines of code to write: 8 lines

  • Estimated time of completion: 20 min

  • Input data: Listing 2.27.

  1. Dane z listingu poniżej skopiuj do pliku “iris.json”

    Listing 2.27. Iris dataset in JSON
    [{"sepalLength":5.1,"sepalWidth":3.5,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.7,"sepalWidth":3.2,"petalLength":1.3,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5,"sepalWidth":3.6,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":5.4,"sepalWidth":3.9,"petalLength":1.7,"petalWidth":0.4,"species":"setosa"},{"sepalLength":4.6,"sepalWidth":3.4,"petalLength":1.4,"petalWidth":0.3,"species":"setosa"},{"sepalLength":5,"sepalWidth":3.4,"petalLength":1.5,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.4,"sepalWidth":2.9,"petalLength":1.4,"petalWidth":0.2,"species":"setosa"},{"sepalLength":4.9,"sepalWidth":3.1,"petalLength":1.5,"petalWidth":0.1,"species":"setosa"},{"sepalLength":7,"sepalWidth":3.2,"petalLength":4.7,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.4,"sepalWidth":3.2,"petalLength":4.5,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":6.9,"sepalWidth":3.1,"petalLength":4.9,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.5,"sepalWidth":2.3,"petalLength":4,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.5,"sepalWidth":2.8,"petalLength":4.6,"petalWidth":1.5,"species":"versicolor"},{"sepalLength":5.7,"sepalWidth":2.8,"petalLength":4.5,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":4.7,"petalWidth":1.6,"species":"versicolor"},{"sepalLength":4.9,"sepalWidth":2.4,"petalLength":3.3,"petalWidth":1,"species":"versicolor"},{"sepalLength":6.6,"sepalWidth":2.9,"petalLength":4.6,"petalWidth":1.3,"species":"versicolor"},{"sepalLength":5.2,"sepalWidth":2.7,"petalLength":3.9,"petalWidth":1.4,"species":"versicolor"},{"sepalLength":6.3,"sepalWidth":3.3,"petalLength":6,"petalWidth":2.5,"species":"virginica"},{"sepalLength":5.8,"sepalWidth":2.7,"petalLength":5.1,"petalWidth":1.9,"species":"virginica"},{"sepalLength":7.1,"sepalWidth":3,"petalLength":5.9,"petalWidth":2.1,"species":"virginica"},{"sepalLength":6.3,"sepalWidth":2.9,"petalLength":5.6,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.5,"sepalWidth":3,"petalLength":5.8,"petalWidth":2.2,"species":"virginica"},{"sepalLength":7.6,"sepalWidth":3,"petalLength":6.6,"petalWidth":2.1,"species":"virginica"},{"sepalLength":4.9,"sepalWidth":2.5,"petalLength":4.5,"petalWidth":1.7,"species":"virginica"},{"sepalLength":7.3,"sepalWidth":2.9,"petalLength":6.3,"petalWidth":1.8,"species":"virginica"},{"sepalLength":6.7,"sepalWidth":2.5,"petalLength":5.8,"petalWidth":1.8,"species":"virginica"},{"sepalLength":7.2,"sepalWidth":3.6,"petalLength":6.1,"petalWidth":2.5,"species":"virginica"}]
    
  2. Odczytaj dane z pliku, i wyświetl je w formacie List[tuple]

  3. Pierwsza linijka ma zawierać nagłówek

  4. Kolejne linie mają mieć dane

The whys and wherefores
  • Deserializacja danych

  • Korzystanie z biblioteki JSON

  • Konwersja typów

  • Praca z plikami

2.6.3. Date serialization

  • Filename: json_datetime.py

  • Lines of code to write: 10 lines

  • Estimated time of completion: 15 min

  • Input data: Listing 2.28.

Listing 2.28. Sample Python data JSON
from datetime import datetime, date


DATA = {
    "astronaut": {
        "date": date(1961, 4, 12),
        "person": "[email protected]"
    },
    "flight": [
        {"datetime": datetime(1969, 7, 21, 14, 56, 15), "action": "landing"}
    ]
}
  1. Skopiuj do swojego pliku strukturę danych Listing 2.28.

  2. Zapisz ją do pliku JSON

  3. Wczytaj ją z pliku JSON jako obiekty Pythona (ten sam efekt co na listingu)

The whys and wherefores
  • Serializacja danych

  • Korzystanie z biblioteki JSON

  • Serializowanie zagnieżdżonych dat i dat z czasem

2.6.4. Serializing custom class to JSON

  • Filename: json_objects.py

  • Lines of code to write: 15 lines

  • Estimated time of completion: 20 min

Listing 2.29. Sample Python data JSON
DATA = [
  {"sepalLength": 5.0, "sepalWidth": 3.6, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 4.9, "sepalWidth": 3.1, "petalLength": 1.5, "petalWidth": 0.1, "species": "setosa"},
  {"sepalLength": 4.9, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 7.0, "sepalWidth": 3.2, "petalLength": 4.7, "petalWidth": 1.4, "species": "versicolor"},
  {"sepalLength": 4.6, "sepalWidth": 3.1, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 6.5, "sepalWidth": 3.0, "petalLength": 5.8, "petalWidth": 2.2, "species": "virginica"},
  {"sepalLength": 7.1, "sepalWidth": 3.0, "petalLength": 5.9, "petalWidth": 2.1, "species": "virginica"},
  {"sepalLength": 6.7, "sepalWidth": 2.5, "petalLength": 5.8, "petalWidth": 1.8, "species": "virginica"},
  {"sepalLength": 5.2, "sepalWidth": 2.7, "petalLength": 3.9, "petalWidth": 1.4, "species": "versicolor"},
  {"sepalLength": 5.0, "sepalWidth": 3.4, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 4.9, "sepalWidth": 2.4, "petalLength": 3.3, "petalWidth": 1.0, "species": "versicolor"},
  {"sepalLength": 6.5, "sepalWidth": 2.8, "petalLength": 4.6, "petalWidth": 1.5, "species": "versicolor"},
  {"sepalLength": 5.4, "sepalWidth": 3.9, "petalLength": 1.7, "petalWidth": 0.4, "species": "setosa"},
  {"sepalLength": 6.3, "sepalWidth": 3.3, "petalLength": 4.7, "petalWidth": 1.6, "species": "versicolor"},
  {"sepalLength": 6.4, "sepalWidth": 3.2, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
  {"sepalLength": 6.6, "sepalWidth": 2.9, "petalLength": 4.6, "petalWidth": 1.3, "species": "versicolor"},
  {"sepalLength": 5.8, "sepalWidth": 2.7, "petalLength": 5.1, "petalWidth": 1.9, "species": "virginica"},
  {"sepalLength": 6.3, "sepalWidth": 2.9, "petalLength": 5.6, "petalWidth": 1.8, "species": "virginica"},
  {"sepalLength": 7.6, "sepalWidth": 3.0, "petalLength": 6.6, "petalWidth": 2.1, "species": "virginica"},
  {"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 7.3, "sepalWidth": 2.9, "petalLength": 6.3, "petalWidth": 1.8, "species": "virginica"},
  {"sepalLength": 4.7, "sepalWidth": 3.2, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 6.9, "sepalWidth": 3.1, "petalLength": 4.9, "petalWidth": 1.5, "species": "versicolor"},
  {"sepalLength": 7.2, "sepalWidth": 3.6, "petalLength": 6.1, "petalWidth": 2.5, "species": "virginica"},
  {"sepalLength": 4.4, "sepalWidth": 2.9, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
  {"sepalLength": 5.5, "sepalWidth": 2.3, "petalLength": 4.0, "petalWidth": 1.3, "species": "versicolor"},
  {"sepalLength": 4.6, "sepalWidth": 3.4, "petalLength": 1.4, "petalWidth": 0.3, "species": "setosa"},
  {"sepalLength": 6.3, "sepalWidth": 3.3, "petalLength": 6.0, "petalWidth": 2.5, "species": "virginica"},
  {"sepalLength": 4.9, "sepalWidth": 2.5, "petalLength": 4.5, "petalWidth": 1.7, "species": "virginica"},
  {"sepalLength": 5.7, "sepalWidth": 2.8, "petalLength": 4.5, "petalWidth": 1.3, "species": "versicolor"}
]
  1. Skopiuj do pliku iris.json dane z listingu Listing 2.29.

  2. Stwórz klasy Setosa, Virginica, Versicolor

  3. Czytając dane z pliku twórz obiekty powyższych klas w zależności od wyniku pomiaru (pole “species”)

The whys and wherefores
  • Serializacja danych

  • Korzystanie z biblioteki JSON

  • Serializowanie zagnieżdżonych obiektów

2.6.5. Deserialize data from GITHub

  • Filename: json_deserialize_github.py

  • Lines of code to write: 15 lines

  • Estimated time of completion: 20 min

  1. Za pomocą biblioteki requests pobierz dane z https://api.github.com/users

  2. Iterując po rekordach twórz obiekty klasy User

The whys and wherefores
  • Deserializacja danych

  • Korzystanie z biblioteki JSON

  • Deserializacja zagnieżdżonych obiektów

  • Reprezentacja klas na podstawie danych otrzymanych przez API

2.6.6. Deserialize

  • Filename: json_deserialize_classes.py

  • Lines of code to write: 30 lines

  • Estimated time of completion: 30 min

  1. Po API dostajesz JSONa tak jak na listingu poniżej

  2. Iterując po rekordach twórz obiekty klasy Astronaut

  3. Sparsuj user_permissions i przedstaw je za pomocą listy klas

  4. Nazwa klasy to klucz w słowniku

  5. Są zawsze cztery pola: "add", "modify", "view", "delete"

  6. Jeżeli jakieś pole jest wymienione, to ma wartość True, jeżeli nie to False

The whys and wherefores
  • Deserializacja danych

  • Korzystanie z biblioteki JSON

  • Deserializacja zagnieżdżonych obiektów

  • Reprezentacja klas na podstawie danych otrzymanych przez API

[{"model":"authorization.user","pk":1,"fields":{"password":"pbkdf2_sha256$120000$gvEBNiCeTrYa0$5C+NiCeTrYsha1PHogqvXNiCeTrY0CRSLYYAA90=","last_login":"1970-01-01T00:00:00.000Z","is_superuser":false,"username":"commander","first_name":"Иван","last_name":"Иванович","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"eclss":["add","modify","view"]},{"communication":["add","modify","view"]},{"medical":["add","modify","view"]},{"science":["add","modify","view"]}]}},{"model":"authorization.user","pk":2,"fields":{"password":"pbkdf2_sha256$120000$eUNiCeTrYHoh$X32NiCeTrYZOWFdBcVT1l3NiCeTrY4WJVhr+cKg=","last_login":null,"is_superuser":false,"username":"executive-officer","first_name":"José","last_name":"Jiménez","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"eclss":["add","modify","view"]},{"communication":["add","modify","view"]},{"medical":["add","modify","view"]},{"science":["add","modify","view"]}]}},{"model":"authorization.user","pk":3,"fields":{"password":"pbkdf2_sha256$120000$3G0RNiCeTrYlaV1$mVb62WNiCeTrYQ9aYzTsSh74NiCeTrY2+c9/M=","last_login":"1970-01-01T00:00:00.000Z","is_superuser":false,"username":"crew-medical-officer","first_name":"Melissa","last_name":"Lewis","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"communication":["add","view"]},{"medical":["add","modify","view"]},{"science":["add","modify","view"]}]}},{"model":"authorization.user","pk":4,"fields":{"password":"pbkdf2_sha256$120000$QmSNiCeTrYBv$Nt1jhVyacNiCeTrYSuKzJ//WdyjlNiCeTrYYZ3sB1r0g=","last_login":null,"is_superuser":false,"username":"science-data-officer","first_name":"Mark","last_name":"Watney","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"communication":["add","view"]},{"science":["add","modify","view"]}]}},{"model":"authorization.user","pk":5,"fields":{"password":"pbkdf2_sha256$120000$bxS4dNiCeTrY1n$Y8NiCeTrYRMa5bNJhTFjNiCeTrYp5swZni2RQbs=","last_login":null,"is_superuser":false,"username":"communication-officer","first_name":"Jan","last_name":"Twardowski","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"communication":["add","modify","view"]},{"science":["add","modify","view"]}]}},{"model":"authorization.user","pk":6,"fields":{"password":"pbkdf2_sha256$120000$aXNiCeTrY$UfCJrBh/qhXohNiCeTrYH8nsdANiCeTrYnShs9M/c=","last_login":null,"is_superuser":false,"username":"eclss-officer","first_name":"Harry","last_name":"Stamper","email":"","is_staff":true,"is_active":true,"date_joined":"1970-01-01T00:00:00.000Z","groups":[1],"user_permissions":[{"communication":["add","view"]},{"eclss":["add","modify","view"]},{"science":["add","modify","view"]}]}}]