Wat is het verschil tussen json.load() en json.loads() functies

Wat is in Python het verschil tussen json.load()en json.loads()?

Ik vermoed dat de functie load()moet worden gebruikt met een bestandsobject (ik moet dus een contextmanager gebruiken) terwijl de functie loads()de pad naar het bestand als een tekenreeks. Het is een beetje verwarrend.

Staat de letter “s” in json.loads()voor string?

Hartelijk dank voor uw antwoorden!


Antwoord 1, autoriteit 100%

Ja, sstaat voor string. De functie json.loadsneemt niet het bestandspad, maar de bestandsinhoud als een tekenreeks. Bekijk de documentatie.


Antwoord 2, autoriteit 51%

Ik ga gewoon een eenvoudig voorbeeld toevoegen aan wat iedereen heeft uitgelegd,

json.load()

json.loadkan een bestand zelf deserialiseren, d.w.z. het accepteert een file-object, bijvoorbeeld

# 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))

uitvoert,

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

Als ik json.loadsgebruik om in plaats daarvan een bestand te openen,

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

Ik krijg deze foutmelding:

TypeError: verwachte string of buffer

json.loads()

json.loads()tekenreeks deserialiseren.

Dus om json.loadste gebruiken, moet ik de inhoud van het bestand doorgeven met de functie read(), bijvoorbeeld

gebruik content.read()met json.loads()retourneer de inhoud van het bestand,

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

Uitvoer,

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

Dat komt omdat het type content.read()een tekenreeks is, d.w.z. <type 'str'>

Als ik json.load()gebruik met content.read(), krijg ik een foutmelding,

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

Geeft,

AttributeError: ‘str’ object heeft geen attribuut ‘read’

Dus nu weet je het json.loaddeserialze-bestand en json.loadsdeserialize een string.

Nog een voorbeeld,

sys.stdinretourneer fileobject, dus als ik print(json.load(sys.stdin))doe, krijg ik werkelijke json-gegevens,

cat json_data.json | ./test.py
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}

Als ik json.loads()wil gebruiken, zou ik in plaats daarvan print(json.loads(sys.stdin.read()))doen.


Antwoord 3, autoriteit 15%

Documentatie is vrij duidelijk: 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]]]]]]]])

Deserialiseer fp (een .read()-ondersteunend bestandsachtig object dat a . bevat
JSON-document) naar een Python-object met behulp van deze conversietabel.

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

Deserialiseer s (een str- of unicode-instantie die een JSON-document bevat)
naar een Python-object met behulp van deze conversietabel.

Dus loadis voor een bestand, loadsvoor een string


Antwoord 4, autoriteit 9%

SNEL ANTWOORD (zeer vereenvoudigd!)

json.load() neemt een BESTAND

json.load() verwacht een bestand (bestandsobject) – b.v. een bestand dat je eerder hebt geopend, gegeven door bestandspad zoals 'files/example.json'.


json.loads() duurt een STRING

json.loads() verwacht een (geldige) JSON-tekenreeks – bijv. {"foo": "bar"}


VOORBEELDEN

Ervan uitgaande dat je een bestand example.jsonhebt met deze inhoud: { “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'

Antwoord 5

In python3.7.7 is de definitie van json.load zoals hieronder volgens cpython-broncode:

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 roept eigenlijk json.loads aan en gebruikt fp.read()als eerste argument.

Dus als uw code is:

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

Het is hetzelfde om dit te doen:

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

Maar als u de bytes wilt specificeren die uit het bestand worden gelezen, zoals fp.read(10)of de string/bytes die u wilt deserialiseren niet uit het bestand komt, moet u json.loads gebruiken ()

Wat betreft json.loads(), het deserialiseert niet alleen string, maar ook bytes. Als sbytes of bytearray is, wordt het eerst gedecodeerd naar string. Je kunt het ook vinden in de broncode.

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')

Other episodes