Was ist der Unterschied zwischen den Funktionen json.load () und json.loads ()?

172

Was ist in Python der Unterschied zwischen json.load()und json.loads()?

Ich denke , dass die Last () Funktion mit einem Dateiobjekt verwendet werden muss (Ich brauche also einen Kontext - Manager zu verwenden) , während die Lasten () Funktion , um den Pfad zur Datei als String nehmen. Es ist ein bisschen verwirrend.

Steht der Buchstabe " s " json.loads()für Zeichenfolge ?

Vielen Dank für Ihre Antworten!

MMF
quelle
1
json.loads(s, *)- Deserialize s(a str, bytesoder bytearraybeispielsweise ein Dokument mit JSON) - docs.python.org/3.6/library/json.html
deceze

Antworten:

160

Ja, ssteht für String. Die json.loadsFunktion verwendet nicht den Dateipfad, sondern den Dateiinhalt als Zeichenfolge. Schauen Sie sich die Dokumentation unter https://docs.python.org/2/library/json.html an !

Gijs
quelle
5
Der verlinkte Artikel verweist auf die falsche Python-Version. Die Frage ist mit 2.7 gekennzeichnet.
RvdK
Antwort von @Sufiyan Ghori bietet schöne Beispiele zusätzlich zu dieser kurzen, aber auf den Punkt Antwort.
Wlad
65

Ich möchte nur ein einfaches Beispiel zu dem hinzufügen, was jeder erklärt hat.

json.load ()

json.loadkann eine Datei selbst deserialisieren, dh sie akzeptiert ein fileObjekt, z.

# open a json file for reading and print content using json.load
with open("/xyz/json_data.json", "r") as content:
  print(json.load(content))

wird ausgegeben,

{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}

Wenn ich json.loadsstattdessen eine Datei öffne,

# you cannot use json.loads on file object
with open("json_data.json", "r") as content:
  print(json.loads(content))

Ich würde diesen Fehler bekommen:

TypeError: erwartete Zeichenfolge oder Puffer

json.loads ()

json.loads() String deserialisieren.

Um zu verwenden, muss json.loadsich den Inhalt der Datei mit der read()Funktion übergeben, zum Beispiel

Verwenden content.read()mit json.loads()Rückgabe Inhalt der Datei,

with open("json_data.json", "r") as content:
  print(json.loads(content.read()))

Ausgabe,

{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}

Das liegt daran, dass die Art der content.read()Zeichenfolge ist, dh<type 'str'>

Wenn ich json.load()mit verwende content.read(), erhalte ich Fehler,

with open("json_data.json", "r") as content:
  print(json.load(content.read()))

Gibt,

AttributeError: Das Objekt 'str' hat kein Attribut 'read'.

Jetzt kennen Sie die json.loadDeserialze-Datei und json.loadsdeserialisieren eine Zeichenfolge.

Ein anderes Beispiel,

sys.stdinRück fileObjekt, also wenn ich tue print(json.load(sys.stdin)), werde ich tatsächlich json Daten erhalten,

cat json_data.json | ./test.py

{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}

Wenn ich verwenden möchte json.loads(), würde ich print(json.loads(sys.stdin.read()))stattdessen tun .

Sufiyan Ghori
quelle
4
BESTE (detaillierte) Antwort. Sollte zur (kurzen) akzeptierten Antwort hochgestimmt werden. Zusammen sind sie stark :-)
Wlad
Nur zu Ihrer Information, mit Python 3.6.5 with open()und json.loads()gibt eine Ausnahme zurück:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy
30

Die Dokumentation ist ziemlich klar: https://docs.python.org/2/library/json.html

json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Deserialisieren Sie fp (ein .read () - unterstützendes dateiähnliches Objekt, das ein JSON-Dokument enthält) mithilfe dieser Konvertierungstabelle in ein Python-Objekt.

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Deserialisieren Sie s (eine Str- oder Unicode-Instanz, die ein JSON-Dokument enthält) mithilfe dieser Konvertierungstabelle in ein Python-Objekt.

So loadist es für eine Datei, loadsfür einestring

RvdK
quelle
1
"Datei wie Objekt" vs "eine str / Unicode-Instanz". Ich verstehe nicht, was nicht klar ist?
RvdK
7

SCHNELLE ANTWORT (sehr vereinfacht!)

json.load () nimmt eine DATEI

json.load () erwartet eine Datei (Dateiobjekt) - z. B. eine Datei, die Sie zuvor geöffnet haben, wie von Dateipfad angegeben 'files/example.json'.


json.loads () nimmt einen STRING

json.loads () erwartet eine (gültige) JSON-Zeichenfolge - dh {"foo": "bar"}


BEISPIELE

Angenommen, Sie haben eine Datei example.json mit folgendem Inhalt: {"key_1": 1, "key_2": "foo", "Key_3": null}

>>> import json
>>> file = open("example.json")

>>> type(file)
<class '_io.TextIOWrapper'>

>>> file
<_io.TextIOWrapper name='example.json' mode='r' encoding='UTF-8'>

>>> json.load(file)
{'key_1': 1, 'key_2': 'foo', 'Key_3': None}

>>> json.loads(file)
Traceback (most recent call last):
  File "/usr/local/python/Versions/3.7/lib/python3.7/json/__init__.py", line 341, in loads
TypeError: the JSON object must be str, bytes or bytearray, not TextIOWrapper


>>> string = '{"foo": "bar"}'

>>> type(string)
<class 'str'>

>>> string
'{"foo": "bar"}'

>>> json.loads(string)
{'foo': 'bar'}

>>> json.load(string)
Traceback (most recent call last):
  File "/usr/local/python/Versions/3.7/lib/python3.7/json/__init__.py", line 293, in load
    return loads(fp.read(),
AttributeError: 'str' object has no attribute 'read'
Wlad
quelle
Tutorial über json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad
1

Die Methode json.load () (ohne "s" in "load") kann eine Datei direkt lesen:

import json
with open('strings.json') as f:
    d = json.load(f)
    print(d)

json.loads () -Methode, die nur für Zeichenfolgenargumente verwendet wird .

import json

person = '{"name": "Bob", "languages": ["English", "Fench"]}'
print(type(person))
# Output : <type 'str'>

person_dict = json.loads(person)
print( person_dict)
# Output: {'name': 'Bob', 'languages': ['English', 'Fench']}

print(type(person_dict))
# Output : <type 'dict'>

Hier können wir nach der Verwendung von Lasten () nimmt einen siehe Zeichenfolge (Typ (str)) als Eingabe und Rückkehr Wörterbuch .

Aditya patil
quelle
0

In python3.7.7 ist die Definition von json.load gemäß dem cpython-Quellcode wie folgt :

def load(fp, *, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):

    return loads(fp.read(),
        cls=cls, object_hook=object_hook,
        parse_float=parse_float, parse_int=parse_int,
        parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)

json.load ruft tatsächlich json.loads auf und verwendet es fp.read()als erstes Argument.

Wenn Ihr Code also lautet:

with open (file) as fp:
    s = fp.read()
    json.loads(s)

Es ist dasselbe, dies zu tun:

with open (file) as fp:
    json.load(fp)

Wenn Sie jedoch die aus der Datei fp.read(10)gelesenen Bytes als "Gefällt mir" angeben müssen oder die Zeichenfolge / Bytes, die Sie deserialisieren möchten, nicht aus der Datei stammen, sollten Sie json.loads () verwenden.

Bei json.loads () werden nicht nur Zeichenfolgen, sondern auch Bytes deserialisiert. Wenn ses sich um Bytes oder Bytearray handelt, wird es zuerst als String dekodiert. Sie finden es auch im Quellcode.

def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
    containing a JSON document) to a Python object.

    ...

    """
    if isinstance(s, str):
        if s.startswith('\ufeff'):
            raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
                                  s, 0)
    else:
        if not isinstance(s, (bytes, bytearray)):
            raise TypeError(f'the JSON object must be str, bytes or bytearray, '
                            f'not {s.__class__.__name__}')
        s = s.decode(detect_encoding(s), 'surrogatepass')
Wenyi Li
quelle