JSON olvasása és írása fájlba Pythonban

Bevezetés

Ebben az útmutatóban megnézzük, hogyan lehet JSON-adatokat olvasni és írni egy fájlból és fájlba Pythonban a json modult.

JSON (JavaScript objektumjelölés) rendkívül népszerű formátum az adatsorosításhoz, tekintve, hogy mennyire általánosan alkalmazható és könnyű – miközben meglehetősen emberbarát is. A legjelentősebb, hogy széles körben használják a webfejlesztő világban, ahol valószínűleg találkozni fog JSON-soros objektumokkal, amelyeket a webhelyről küldenek. REST API-k, alkalmazáskonfiguráció, vagy akár egyszerű adattárolás.

Elterjedtségéből adódóan a JSON-fájlok (vagy karakterláncok) olvasása és elemzése meglehetősen gyakori, és ugyanilyen gyakori az elküldendő JSON írása is. Ebben az útmutatóban – megvizsgáljuk, hogyan lehet kihasználni a json modul a JSON olvasásához és írásához Pythonban.

JSON írása fájlba Python segítségével a json.dump() és json.dumps() segítségével

JSON-tartalom írása egy fájlba Pythonban – használhatjuk json.dump() és a json.dumps(). Ezek külön módszerek és más eredményt érhet el:

  • json.dumps() – Sorosoz egy objektumot JSON-formátumúvá húr
  • json.dump() – Sorosított egy objektumot JSON adatfolyamba, hogy fájlba vagy socketbe mentse

Jegyzet: Az „s” a „dömperekben” valójában a rövidítése "kidobó húr".

A JSON természetes formátuma hasonló a térkép számítástechnikában – egy térképet key-value párok. Pythonban a szótár egy térkép-megvalósítás, így természetesen képesek leszünk a JSON-t hűen ábrázolni a dict. A szótár tartalmazhat más beágyazott szótárakat, tömböket, logikai értékeket vagy más primitív típusokat, például egész számokat és karakterláncokat.

:::

Jegyzet: A beépített json csomag számos kényelmi módszert kínál, amelyek lehetővé teszik számunkra a JSON és a szótárak közötti konvertálást.

:::

Ennek ellenére importáljuk a json modult, definiáljon egy szótárt bizonyos adatokkal, majd konvertálja JSON-ba, mielőtt fájlba menti:

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)

Ennek eredményeként:

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

Itt van egy egyszerű szótárunk néhányból employees, amelyek mindegyike rendelkezik egy name, department és a place Az dumps() funkció json modul guba egy szótárat a JSON-tartalomba, és visszaadja a JSON karakterlánc.

A szerializálás után dönthet úgy, hogy elküldi egy másik szolgáltatásnak, amely deszerializálja, vagy mondjuk eltárolja. Ha ezt a JSON-karakterláncot fájlban szeretné tárolni, egyszerűen megnyitunk egy fájlt írási módban, és felírjuk. Ha nem szeretné az adatokat független változóba bontani későbbi felhasználás céljából, hanem csak egy fájlba szeretné kiírni, akkor kihagyhatja a dumps() funkciója és használata 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)

Bármely fájlszerű objektum átadható a második argumentumnak dump() függvényt, még ha nem is tényleges fájl. Jó példa erre egy socket, amely ugyanúgy megnyitható, bezárható és beleírható, mint egy fájl.

JSON olvasása fájlból Python segítségével a json.load() és json.loads() függvényekkel

A szótár tartalma és a JSON-karakterlánc közötti leképezés egyszerű, így könnyen konvertálható a kettő között. Ugyanaz a logika, mint a dump() és a dumps() alkalmazva load() és a loads(). Akárcsak json.dumps(), a json.loads() függvény elfogad egy JSON karakterláncot, és szótárrá alakítja, míg json.load() fájlba tölthető be:

import json

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

Ennek eredményeként:

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

Alternatív megoldásként olvassunk be egy JSON-karakterláncot egy szótárba:

import json

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

Ami a következőket is eredményezi:

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

Ez különösen hasznos a JSON-t küldő REST API-válaszok elemzéséhez. Ezek az adatok egy karakterláncként érkeznek hozzád, amelyet aztán továbbíthatsz json.loads() közvetlenül, és sokkal könnyebben kezelhető szótárral dolgozhat!

Rendezés, szép nyomtatás, elválasztók és kódolás

Amikor az adatokat JSON formátumba szerializálja Pythonnal, az üzenetek továbbításához szükséges memória minimalizálását célzó szabványos formátum nem nagyon olvasható, mivel a szóközök megszűnnek. Bár ez az ideális viselkedés az adatátvitelhez (a számítógépek nem törődnek az olvashatósággal, de a mérettel igen) – néha előfordulhat, hogy apró változtatásokat kell végrehajtania, például szóközt kell hozzáadnia, hogy az ember számára olvasható legyen.

Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!

Jegyzet: json.dump()/json.dumps() és a json.load()/json.loads() mindegyik néhány formázási lehetőséget biztosít.

Szépen nyomtatható JSON Pythonban

A JSON ember által olvashatóvá tétele (más néven “szép nyomdai”) olyan egyszerű, mint egy egész érték átadása a indent paraméter:

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

Ez minden új logikai blokkon 4 szóközű behúzást hajt végre:

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

Egy másik lehetőség a parancssori eszköz használata – json.tool. Ezzel szépen kinyomtathatja a JSON-t a parancssorban anélkül, hogy befolyásolná a továbbított karakterláncot, és csak befolyásolná a szabványos kimeneti csőben való megjelenítését:

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

JSON-objektumok rendezése kulcsok szerint

JSON kifejezéssel:

"Az objektum név/érték párok rendezetlen halmaza."

A kulcssorrend nem garantált, de előfordulhat, hogy kényszerítenie kell a kulcssorrendet. A rendelés eléréséhez passzolhat True hoz sort_keys opció használat közben 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))

Ennek eredményeként:

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

ASCII szöveg és kódolás

Alapértelmezésben, json.dump() és a json.dumps() biztosítja, hogy az adott Python szótár szövege ASCII-kódolású legyen. Ha nem ASCII-karakterek vannak jelen, akkor a rendszer automatikusan kihagyja őket, amint az a következő példában látható:

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

Ez nem mindig elfogadható, és sok esetben érdemes változatlanul hagyni a Unicode karaktereket. Ehhez állítsa be a ensure_ascii lehetőség False:

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

Az egyéni kulcsadattípusok kihagyása

Ha a szótárban egy kulcs nem primitív típusú (str, int, float, bool or None) A TypeError akkor jelenik meg, amikor megpróbálja kiírni a JSON-tartalmat egy fájlba. Ezeket a gombokat átugorhatja a skipkeys érv:

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

A körkörös ellenőrzés engedélyezése és letiltása

Ha egy JSON-objektum egy tulajdonsága önmagára vagy egy másik objektumra hivatkozik, amely a szülőobjektumra hivatkozik, akkor egy végtelenül rekurzív JSON jön létre. A végtelen rekurzió általában a memória gyors lefoglalását eredményezi, amíg az eszköz memóriája el nem fogy, és a JSON kiíratása esetén RecursionError emelik, és a dömpinget leállítják.

Ezt szabályozza a check_circular zászló, ami True alapértelmezés szerint, és megakadályozza a lehetséges problémákat a körkörös függőségek írásakor. A kikapcsolásához állítsa „False” értékre:

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

Jegyezze meg azonban, hogy ez az nagyon nem ajánlott.

NaN engedélyezése és letiltása

NaN-értékek, mint pl -inf, inf és a nan bekúszhat olyan objektumokba, amelyeket szerializálni vagy deszerializálni szeretne. JSON szabvány nem engedi NaN értékekhez, de ezek továbbra is logikai értéket hordoznak, amelyet esetleg üzenetben szeretne továbbítani. Másrészt – érdemes lehet érvényesíteni ezeket a NaN értékeket nem továbbítani, és helyette kivételt kell tenni. Az allow_nan a zászló be van állítva True alapértelmezés szerint, és lehetővé teszi a NaN értékek szerializálását és deszerializálását, lecserélve őket a JavaScript megfelelőire (Inifinity, -Infinity és a NaN).

Ha beállítja a zászlót False ehelyett – szigorúan JSON-szabványos formátumra vált, ami felveti a ValueError ha az objektumok a következő értékekkel rendelkező attribútumokat tartalmazzák:

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

Elválasztók cseréje

A JSON-ban a kulcsokat kettősponttal választják el az értékektől (:) és az elemeket vesszővel választjuk el egymástól (,):

key1:value1,
key2:value2

Az alapértelmezett elválasztók a JSON olvasásához és írásához a Pythonban (', ', ': ') val vel szóközöknek a vessző és a kettőspont után. Módosíthatja ezeket a szóközök kihagyásához, és így egy kicsit tömörebbé teheti a JSON-t, vagy teljesen megváltoztathatja az elválasztókat más speciális karakterekkel egy másik megjelenítéshez:


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

Kompatibilitási problémák a Python 2-vel

Ha a Python régebbi verzióját (2.x) használja, akkor előfordulhat, hogy a TypeError miközben megpróbálja kiírni a JSON-tartalmat egy fájlba. Ugyanis, ha a tartalom nem ASCII karaktert tartalmaz, a TypeError emelkedett, még ha átadja a kódolási argumentumot, amikor a json.dump() eljárás:


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

Ha találkozik ezzel az éles esettel, amelyet azóta a következő Python-verziókban javítottak, próbálja meg használni json.dumps() ehelyett, és írja be a karakterlánc tartalmát egy fájlba, ahelyett, hogy a tartalmat közvetlenül egy fájlba továbbítaná.

Következtetés

Ebben az útmutatóban bemutattuk Önnek a json.dump(), json.dumps(), json.load()és json.loads() metódusok, amelyek segítenek a JSON-karakterláncok szerializálásában és deszerializálásában.

Ezután megvizsgáltuk, hogyan rendezheti a JSON-objektumokat, hogyan nyomtathatja ki őket, módosíthatja a kódolást, kihagyhatja az egyéni kulcsadattípusokat, engedélyezheti vagy letilthatja a körkörös ellenőrzéseket, és hogy engedélyezettek-e a NaN-ek, valamint hogyan módosíthatja az elválasztókat szerializálás és deszerializálás.

Mivel a JSON a strukturált adatok sorosításának egyik legnépszerűbb módja, valószínűleg gyakran kell majd vele kommunikálnia, különösen, ha webalkalmazásokon dolgozik. Python json modul nagyszerű módja az indulásnak, bár valószínűleg meg fogja találni simplejson egy másik nagyszerű alternatíva, amely sokkal kevésbé szigorú a JSON-szintaxist illetően.

Időbélyeg:

Még több Stackabus