Læsning og skrivning af JSON til en fil i Python

Introduktion

I denne vejledning tager vi et kig på, hvordan man læser og skriver JSON-data fra og til en fil i Python ved hjælp af json modul.

JSON (JavaScript Object Notation) er et ekstremt populært format til dataserialisering, i betragtning af hvor generelt anvendeligt og let det er – samtidig med at det er ret menneskevenligt. Mest bemærkelsesværdigt er det flittigt brugt i webudviklingsverdenen, hvor du sandsynligvis vil støde på JSON-serialiserede objekter, der sendes fra REST API'er, applikationskonfiguration eller endda simpel datalagring.

I betragtning af dens udbredelse er læsning og parsing af JSON-filer (eller strenge) ret almindeligt, og det er lige så almindeligt at skrive JSON for at blive sendt afsted. I denne guide – vi tager et kig på, hvordan man udnytter json modul til at læse og skrive JSON i Python.

Skrive JSON til en fil med Python med json.dump() og json.dumps()

At skrive JSON-indhold til en fil i Python – vi kan bruge json.dump() , json.dumps(). Disse er separate metoder og opnå et andet resultat:

  • json.dumps() – Serialiserer et objekt til et JSON-formateret streng
  • json.dump() – Serialiserede et objekt til en JSON-stream til lagring i filer eller sockets

Bemærk: "S" i "dumps" er faktisk en forkortelse for "dump string".

JSONs naturlige format ligner en kort i datalogi – et kort over key-value par. I Python, en ordbog er en kortimplementering, så vi vil naturligvis være i stand til at repræsentere JSON trofast gennem en dict. En ordbog kan indeholde andre indlejrede ordbøger, arrays, booleaner eller andre primitive typer som heltal og strenge.

:::

Bemærk: Den indbyggede json pakken tilbyder flere bekvemmelighedsmetoder, der giver os mulighed for at konvertere mellem JSON og ordbøger.

:::

Når det er sagt, lad os importere json modul, definere en ordbog med nogle data og derefter konvertere den til JSON, før du gemmer til en fil:

import json

data = {
    'employees' : [
        {
            'name' : 'John Doe',
            'department' : 'Marketing',
            'place' : 'Remote'
        },
        {
            'name' : 'Jane Doe',
            'department' : 'Software Engineering',
            'place' : 'Remote'
        },
        {
            'name' : 'Don Joe',
            'department' : 'Software Engineering',
            'place' : 'Office'
        }
    ]
}


json_string = json.dumps(data)
print(json_string)

Dette resulterer i:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Her har vi en simpel ordbog med nogle få employees, som hver har en name, department , place. Det dumps() funktion af json modul lossepladser en ordbog ind i JSON-indhold, og returnerer en JSON-streng.

Når det er serialiseret, kan du beslutte at sende det til en anden tjeneste, der vil deserialisere det, eller for eksempel gemme det. For at gemme denne JSON-streng i en fil, åbner vi blot en fil i skrivetilstand og skriver den ned. Hvis du ikke ønsker at udtrække dataene til en uafhængig variabel til senere brug og bare gerne vil dumpe dem i en fil, kan du springe over dumps() funktion og brug dump() instad:


with open('json_data.json', 'w') as outfile:
    outfile.write(json_string)


with open('json_data.json', 'w') as outfile:
    json.dump(json_string, outfile)

Ethvert fillignende objekt kan overføres til det andet argument i dump() funktion, selvom det ikke er en egentlig fil. Et godt eksempel på dette ville være en socket, som kan åbnes, lukkes og skrives meget som en fil.

Læsning af JSON fra en fil med Python med json.load() og json.loads()

Kortlægningen mellem ordbogsindhold og en JSON-streng er ligetil, så det er nemt at konvertere mellem de to. Samme logik som med dump() , dumps() anvendes til load() , loads(). Meget ligesom json.dumps(), json.loads() funktion accepterer en JSON-streng og konverterer den til en ordbog, mens json.load() lader dig indlæse en fil:

import json

with open('json_data.json') as json_file:
    data = json.load(json_file)
    print(data)

Dette resulterer i:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Lad os alternativt læse en JSON-streng ind i en ordbog:

import json

python_dictionary = json.loads(json_string)
print(python_dictionary)

Hvilket også resulterer i:

{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}

Denne er især nyttig til at parse REST API-svar, der sender JSON. Disse data kommer til dig som en streng, som du derefter kan videregive til json.loads() direkte, og du har en meget mere overskuelig ordbog at arbejde med!

Sortering, Pretty-Printing, Separatorer og Encoding

Når du serialiserer dine data til JSON med Python, er standardformatet, der sigter mod at minimere den nødvendige hukommelse til at sende beskeder, ikke særlig læsbart, da hvide mellemrum er elimineret. Selvom dette er den ideelle adfærd til dataoverførsel (computere er ligeglade med læsbarhed, men bekymrer sig om størrelse) – nogle gange kan du være nødt til at foretage små ændringer, som f.eks. at tilføje mellemrum for at gøre det læsbart for mennesker.

Tjek vores praktiske, praktiske guide til at lære Git, med bedste praksis, brancheaccepterede standarder og inkluderet snydeark. Stop med at google Git-kommandoer og faktisk lærer det!

Bemærk: json.dump()/json.dumps() , json.load()/json.loads() alle giver et par muligheder for formatering.

Pretty-Printing JSON i Python

Gør JSON menneskelig læsbar (aka "pænt udskrivning") er lige så let som at sende en heltalsværdi for indent parameter:

import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, indent=4))

Dette folder en 4-mellemrums indrykning på hver ny logisk blok:

{
    "people": [
        {
            "website": "stackabuse.com", 
            "from": "Nebraska", 
            "name": "Scott"
        }
    ]
}

En anden mulighed er at bruge kommandolinjeværktøjet - json.tool. Med det kan du smukt udskrive JSON'en på kommandolinjen uden at påvirke den transmitterede streng og bare påvirke, hvordan den vises på standardoutputrøret:

$ echo '{"people":[{"name":"Scott", "website":"stackabuse.com", "from":"Nebraska"}]}' | python -m json.tool
{
    "people": [
        {
            "name": "Scott",
            "website": "stackabuse.com"
            "from": "Nebraska",
        }
    ]
}

Sortering af JSON-objekter efter nøgler

I JSON-termer:

"Et objekt er et uordnet sæt navn/værdi-par."

Nøglerækkefølgen er ikke garanteret, men det er muligt, at du muligvis skal håndhæve nøgleordren. For at opnå bestilling kan du bestå True til sort_keys mulighed ved brug json.dump() or json.dumps():

import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, sort_keys=True, indent=4))

Dette resulterer i:

{
    "people": [
        {
            "from": "Nebraska",
            "name": "Scott",
            "website": "stackabuse.com"
        }
    ]
}

ASCII-tekst og kodning

Som standard json.dump() , json.dumps() vil sikre, at teksten i den givne Python-ordbog er ASCII-kodet. Hvis ikke-ASCII-tegn er til stede, escapes de automatisk, som vist i følgende eksempel:

import json
data = {'item': 'Beer', 'cost':'£4.00'}
jstr = json.dumps(data, indent=4)
print(jstr)
{
    "item": "Beer",
    "cost": "u00a34.00"
}

Dette er ikke altid acceptabelt, og i mange tilfælde vil du måske beholde dine Unicode-tegn uændret. For at gøre dette skal du indstille ensure_ascii mulighed for at False:

jstr = json.dumps(data, ensure_ascii=False, indent=4)
print(jstr)
{
    "item": "Beer",
    "cost": "£4.00"
}

Spring over brugerdefinerede nøgledatatyper

Hvis en nøgle i din ordbog er af en ikke-primitiv type (str, int, float, bool or None) Af de TypeError hæves, når du prøver at dumpe JSON-indhold i en fil. Du kan springe disse taster over via skipkeys argument:

jstr = json.dumps(data, skipkeys=True)

Aktivering og deaktivering af Circular Check

Hvis en egenskab for et JSON-objekt refererer til sig selv, eller et andet objekt, der refererer tilbage til det overordnede objekt – oprettes en uendeligt rekursiv JSON. Uendelig rekursion resulterer typisk i, at hukommelsen allokeres hurtigt, indtil en enhed løber tør for hukommelse, og i tilfælde af dumping af JSON, en RecursionError hæves og dumpningen standses.

Dette er reguleret af check_circular flag, hvilket er True som standard og forhindrer mulige problemer ved skrivning af cirkulære afhængigheder. For at slå det fra, kan du indstille det til "False:

jstr = json.dumps(data, check_circular=False)

Bemærk dog, at dette er stærkt ikke anbefalet.

Aktivering og deaktivering af NaN'er

NaN-værdier, som f.eks -inf, inf , nan kan krybe ind i objekter, som du vil serialisere eller deserialisere. JSON standard tillader ikke for NaN-værdier, men de har stadig logisk værdi, som du måske ønsker at overføre i en besked. På den anden side – du ønsker måske at håndhæve disse NaN-værdier er ikke overføres, og i stedet rejse en undtagelse. Det allow_nan flag er sat til True som standard og giver dig mulighed for at serialisere og deserialisere NaN-værdier, og erstatte dem med JavaScript-ækvivalenter (Inifinity, -Infinity , NaN).

Hvis du sætter flaget til False i stedet – skifter du til et strengt JSON-standardiseret format, hvilket hæver en ValueError hvis dine objekter indeholder attributter med disse værdier:

jstr = json.dumps(data, allow_nan=False)

Udskiftning af separatorer

I JSON er nøglerne adskilt fra værdier med kolon (:) og emnerne er adskilt fra hinanden med kommaer (,):

key1:value1,
key2:value2

Standardseparatorerne til at læse og skrive JSON i Python er (', ', ': ') med blanke efter kommaer og koloner. Du kan ændre disse for at springe mellemrum over og dermed gøre JSON en smule mere kompakt, eller helt ændre separatorerne med andre specialtegn for en anden repræsentation:


jstr = json.dumps(data, separators=(',', ':'))

Kompatibilitetsproblemer med Python 2

Hvis du bruger en ældre version af Python (2.x) – kan du støde på en TypeError mens du forsøger at dumpe JSON-indhold i en fil. Nemlig, hvis indholdet indeholder et ikke-ASCII-tegn, en TypeError er rejst, selvom du sender indkodningsargumentet, når du bruger json.dump() metode:


with open('json_data.json', 'w', encoding='utf-8') as outfile:
    json.dump(json_string, outfile, ensure_ascii=False)

Hvis du støder på denne kant-case, som siden er blevet rettet i efterfølgende Python-versioner – prøv at bruge json.dumps() i stedet, og skriv strengindholdet ind i en fil i stedet for at streame indholdet direkte til en fil.

Konklusion

I denne guide introducerede vi dig til json.dump(), json.dumps(), json.load()og json.loads() metoder, som hjælper med at serialisere og deserialisere JSON-strenge.

Vi har derefter taget et kig på, hvordan du kan sortere JSON-objekter, smukt udskrive dem, ændre kodningen, springe tilpassede nøgledatatyper over, aktivere eller deaktivere cirkulære kontroller, og om NaN'er er tilladt, samt hvordan du ændrer separatorerne for serialisering og deserialisering.

Da JSON er en af ​​de mest populære måder at serialisere strukturerede data på, bliver du sandsynligvis nødt til at interagere med det ret ofte, især når du arbejder med webapplikationer. Python's json modul er en god måde at komme i gang på, selvom du nok vil finde det simplejson er et andet godt alternativ, der er meget mindre streng på JSON-syntaks.

Tidsstempel:

Mere fra Stablemisbrug