Qual è la differenza tra le funzioni json.load () e json.loads ()


173

In Python, qual è la differenza tra json.load()e json.loads()?

Credo che il load () funzione deve essere utilizzata con un oggetto file (ho bisogno quindi di utilizzare un gestore di contesto), mentre i () carichi funzione prendono il percorso del file come una stringa. È un po 'confuso.

La lettera " s " json.loads()sta per stringa ?

Grazie mille per le tue risposte!


1
json.loads(s, *)- Deserializza s(a str, byteso bytearrayistanza contenente un documento JSON) - docs.python.org/3.6/library/json.html
decreze

Risposte:


160

Sì, ssta per stringa. La json.loadsfunzione non accetta il percorso del file, ma il contenuto del file come stringa. Guarda la documentazione su https://docs.python.org/2/library/json.html !


5
L'articolo collegato punta alla versione errata di Python. La domanda è taggata come 2.7.
RvdK,

la risposta di @Sufiyan Ghori fornisce esempi interessanti oltre a questa risposta breve ma precisa.
Wlad

65

Aggiungerò solo un semplice esempio di ciò che tutti hanno spiegato,

json.load ()

json.loadpuò deserializzare un file stesso, ovvero accetta un fileoggetto, ad esempio,

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

uscirà,

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

Se invece utilizzo json.loadsun file,

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

Vorrei ottenere questo errore:

TypeError: stringa o buffer previsti

json.loads ()

json.loads() deserializzare la stringa.

Quindi per poter usare json.loadsdovrò passare il contenuto del file usando la read()funzione, ad esempio

utilizzando content.read()con il json.loads()contenuto di ritorno del file,

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

Produzione,

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

Questo perché il tipo di content.read()è stringa, cioè<type 'str'>

Se lo utilizzo json.load()con content.read(), visualizzerò un errore,

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

dà,

AttributeError: l'oggetto 'str' non ha attributi 'read'

Quindi, ora conosci il json.loadfile json.loadsdeserialze e deserializza una stringa.

Un altro esempio,

sys.stdinrestituire fileoggetto, quindi se lo faccio print(json.load(sys.stdin)), otterrò dati json effettivi,

cat json_data.json | ./test.py

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

Se voglio usare json.loads(), lo farei print(json.loads(sys.stdin.read()))invece.


4
MIGLIORE risposta (dettagliata). Dovrebbe essere votato per accompagnare la risposta (breve) accettata. Insieme sono forti :-)
Wlad

Cordiali saluti, con Python 3.6.5 with open()e json.loads()restituisce un'eccezione:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy,

30

La documentazione è abbastanza chiara: 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]]]]]]]])

Deserializza fp (un .read () - che supporta un oggetto simile a un file contenente un documento JSON) in un oggetto Python usando questa tabella di conversione.

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

Deserializza s (un'istanza str o unicode contenente un documento JSON) in un oggetto Python usando questa tabella di conversione.

Lo stesso loadvale per un file, loadsper astring


1
"File come oggetto" vs "un'istanza str / unicode". Non capisco cosa non sia chiaro?
RvdK,

7

RISPOSTA RAPIDA (molto semplificata!)

json.load () accetta un FILE

json.load () si aspetta un file (oggetto file) - ad esempio un file che hai aperto prima dato da filepath come 'files/example.json'.


json.loads () accetta una STRING

json.loads () prevede una stringa JSON (valida), ad es {"foo": "bar"}


ESEMPI

Supponendo di avere un file example.json con questo contenuto: {"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'

Tutorial su json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad

1

Il metodo json.load () (senza "s" in "load") può leggere direttamente un file:

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

Metodo json.loads () , utilizzato solo per argomenti stringa .

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

Qui, possiamo vedere dopo aver usato load () accetta una stringa (type (str)) come dizionario di input e di ritorno .


0

In python3.7.7, la definizione di json.load è la seguente in base al codice sorgente di cpython :

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 in realtà chiama json.loads e lo usa fp.read()come primo argomento.

Quindi se il tuo codice è:

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

È lo stesso per fare questo:

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

Ma se è necessario specificare i byte che leggono dal file come like fp.read(10)o la stringa / byte che si desidera deserializzare non provengono da file, è necessario utilizzare json.loads ()

Per quanto riguarda json.loads (), non solo deserializza la stringa ma anche i byte. Se sè byte o byte, verrà prima decodificato in stringa. Puoi trovarlo anche nel codice sorgente.

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')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.