Python Language
JSON-module
Zoeken…
Opmerkingen
Raadpleeg de officiële documentatie voor volledige documentatie, inclusief versie-specifieke functionaliteit.
Types
defaults
de json
module zal standaard codering en decodering van de onderstaande typen verwerken:
De-serialisatie types:
JSON | Python |
---|---|
voorwerp | dict |
rangschikking | lijst |
draad | str |
nummer (int) | int |
nummer (echt) | vlotter |
waar onwaar | Waar onwaar |
nul | Geen |
De json
module begrijpt ook NaN
, Infinity
en -Infinity
als hun bijbehorende json
, die buiten de JSON-specificatie vallen.
Serialisatiesoorten:
Python | JSON |
---|---|
dict | voorwerp |
lijst, tuple | rangschikking |
str | draad |
int, float, (int / float) afgeleide Enums | aantal |
waar | waar |
vals | vals |
Geen | nul |
Om codering van NaN
, Infinity
en -Infinity
staan, moet u coderen met allow_nan=False
. Hierdoor wordt een ValueError
als u probeert deze waarden te coderen.
Aangepaste (de-) serialisatie
Er zijn verschillende hooks waarmee u gegevens kunt verwerken die anders moeten worden weergegeven. Met behulp van functools.partial
kunt u de relevante parameters voor het gemak gedeeltelijk op deze functies toepassen.
serialization:
U kunt een functie bieden die op objecten werkt voordat ze als volgt worden geserialiseerd:
# 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-serialisatie:
Er zijn verschillende haken die worden afgehandeld door de json-functies, zoals object_hook en parse_float. Voor een volledige lijst voor uw versie van python, zie hier .
# 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)
Verdere aangepaste (de-) serialisatie:
De json
module maakt ook uitbreiding / vervanging van de json.JSONEncoder
en json.JSONDecoder
mogelijk voor diverse typen. De hierboven beschreven haken kunnen als standaard worden toegevoegd door een methode met een vergelijkbare naam te maken. Om deze te gebruiken, geeft u de klasse als de parameter cls
aan de relevante functie. Met behulp van functools.partial
kunt u de cls-parameter gedeeltelijk op deze functies toepassen, bijvoorbeeld
# 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)
JSON maken van Python dict
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
json.dumps(d)
Het bovenstaande fragment retourneert het volgende:
'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
Python dict maken van JSON
import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)
Het bovenstaande fragment retourneert het volgende:
{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}
Gegevens opslaan in een bestand
Het volgende fragment codeert de gegevens die zijn opgeslagen in d
in JSON en slaat deze op in een bestand (vervang de filename
door de werkelijke naam van het bestand).
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
with open(filename, 'w') as f:
json.dump(d, f)
Gegevens uit een bestand ophalen
Het volgende fragment opent een JSON-gecodeerd bestand (vervang filename
door de werkelijke naam van het bestand) en retourneert het object dat in het bestand is opgeslagen.
import json
with open(filename, 'r') as f:
d = json.load(f)
`load` vs` load`, `dump` vs` dumps`
De json
module bevat functies voor zowel lezen als schrijven naar en van Unicode-tekenreeksen, en lezen en schrijven naar en van bestanden. Deze worden onderscheiden door een achterste s
in de naam functie. In deze voorbeelden gebruiken we een StringIO-object, maar dezelfde functies zouden van toepassing zijn op elk bestandachtig object.
Hier gebruiken we de op snaren gebaseerde functies:
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": []}
En hier gebruiken we de bestandsgebaseerde functies:
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": []}
Zoals u kunt zien, is het belangrijkste verschil dat u bij het dumpen van json-gegevens de bestandsingang moet doorgeven aan de functie, in tegenstelling tot het vastleggen van de retourwaarde. Vermeldenswaard is ook dat u naar het begin van het bestand moet zoeken voordat u leest of schrijft, om gegevensbeschadiging te voorkomen. Bij het openen van een bestand wordt de cursor op positie 0
, dus het onderstaande zou ook werken:
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": []}
Het hebben van beide manieren van omgaan met JSON data kunt u idiomatische en efficiënt werken met formats die voortbouwen op JSON, zoals 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')
Oproepen van `json.tool` vanaf de opdrachtregel naar mooie JSON-uitvoer
Gegeven een JSON-bestand "foo.json" zoals:
{"foo": {"bar": {"baz": 1}}}
we kunnen de module rechtstreeks vanaf de opdrachtregel oproepen (de bestandsnaam doorgeven als argument) om deze mooi af te drukken:
$ python -m json.tool foo.json
{
"foo": {
"bar": {
"baz": 1
}
}
}
De module neemt ook input van STDOUT, dus we zouden (in Bash) evenveel kunnen doen:
$ cat foo.json | python -m json.tool
JSON-uitvoer formatteren
Laten we zeggen dat we de volgende gegevens hebben:
>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Gewoon dumpen omdat JSON hier niets bijzonders doet:
>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Inspringing instellen om mooiere uitvoer te krijgen
Als we mooie afdrukken willen, kunnen we een indent
:
>>> print(json.dumps(data, indent=2))
{
"cats": [
{
"name": "Tubbs",
"color": "white"
},
{
"name": "Pepper",
"color": "black"
}
]
}
Sorteer toetsen alfabetisch voor consistente uitvoer
Standaard is de volgorde van toetsen in de uitvoer niet gedefinieerd. We kunnen ze in alfabetische volgorde krijgen om ervoor te zorgen dat we altijd dezelfde uitvoer krijgen:
>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}
Witruimte verwijderen om compacte uitvoer te krijgen
Misschien willen we de overbodige spaties verwijderen, wat gebeurt door de scheidingstekens anders in te stellen dan de standaard ', '
en ': '
:
>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}
JSON die aangepaste objecten codeert
Als we het volgende proberen:
import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)}
print(json.dumps(data))
krijgen we een foutmelding dat TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable
.
Om het datetime-object goed te kunnen serialiseren, moeten we aangepaste code schrijven om het te converteren:
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)
en gebruik vervolgens deze encoderklasse in plaats van json.dumps
:
encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}