Quelle est la différence entre les fonctions json.load () et json.loads ()

173

En Python, quelle est la différence entre json.load()et json.loads()?

Je suppose que la charge () fonction doit être utilisée avec un objet de fichier (je dois donc d'utiliser un gestionnaire de contexte) alors que les charges () fonction prennent le chemin vers le fichier en tant que chaîne. C'est un peu déroutant.

La lettre « s » json.loads()représente-t-elle une chaîne ?

Merci beaucoup pour vos réponses!

MMF
la source
1
json.loads(s, *)- Deserialize s(un str, bytesou par bytearrayexemple contenant un document JSON) - docs.python.org/3.6/library/json.html
deceze

Réponses:

160

Oui, ssignifie chaîne. La json.loadsfonction ne prend pas le chemin du fichier, mais le contenu du fichier sous forme de chaîne. Regardez la documentation sur https://docs.python.org/2/library/json.html !

Gijs
la source
5
L'article lié pointe vers la mauvaise version de python. La question porte la mention 2.7.
RvdK
La réponse de @Sufiyan Ghori fournit de beaux exemples en plus de cette réponse courte mais précise.
Wlad
65

Je vais juste ajouter un exemple simple à ce que tout le monde a expliqué,

json.load ()

json.loadpeut désérialiser un fichier lui-même c'est-à-dire qu'il accepte un fileobjet, par exemple,

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

sortira,

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

Si j'utilise json.loadspour ouvrir un fichier à la place,

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

J'obtiendrais cette erreur:

TypeError: chaîne ou tampon attendu

json.loads ()

json.loads() désérialiser la chaîne.

Donc, pour utiliser, json.loadsje devrai transmettre le contenu du fichier en utilisant la read()fonction, par exemple,

utilisation content.read()avec le json.loads()contenu de retour du fichier,

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

Production,

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

C'est parce que le type de content.read()est une chaîne, ie<type 'str'>

Si j'utilise json.load()avec content.read(), j'obtiendrai une erreur,

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

Donne,

AttributeError: l'objet 'str' n'a pas d'attribut 'read'

Donc, maintenant vous savez json.loaddésérialiser le fichier et json.loadsdésérialiser une chaîne.

Un autre exemple,

sys.stdinreturn fileobject, donc si je le fais print(json.load(sys.stdin)), j'obtiendrai les données json réelles,

cat json_data.json | ./test.py

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

Si je veux utiliser json.loads(), je le ferais à la print(json.loads(sys.stdin.read()))place.

Soufiyan Ghori
la source
4
MEILLEURE réponse (détaillée). Devrait être voté pour accompagner la réponse (courte) acceptée. Ensemble, ils sont forts :-)
Wlad
Juste pour info, avec Python 3.6.5 with open()et json.loads()renvoie une exception:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy
31

La documentation est assez claire: 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]]]]]]]])

Désérialiser fp (un .read () - objet de type fichier prenant en charge contenant un document JSON) en un objet Python à l'aide de cette table de conversion.

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

Désérialisez s (une instance str ou unicode contenant un document JSON) en un objet Python à l'aide de cette table de conversion.

Il en loadva de même pour un fichier, loadspour unstring

RvdK
la source
1
"Fichier comme objet" vs "une instance str / unicode". Je ne comprends pas ce qui n'est pas clair?
RvdK
7

RÉPONSE RAPIDE (très simplifiée!)

json.load () prend un FICHIER

json.load () attend un fichier (objet fichier) - par exemple un fichier que vous avez ouvert avant donné par filepath comme 'files/example.json'.


json.loads () prend un STRING

json.loads () attend une chaîne JSON (valide) - ie {"foo": "bar"}


EXEMPLES

En supposant que vous ayez un fichier example.json avec ce contenu: {"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
la source
Tutoriel about json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad
1

La méthode json.load () (sans "s" dans "load") peut lire un fichier directement:

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

json.loads () , qui n'est utilisée que pour les arguments de chaîne .

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

Ici, nous pouvons voir qu'après avoir utilisé load () prend une chaîne (type (str)) comme dictionnaire d' entrée et de retour .

Aditya patil
la source
0

En python3.7.7, la définition de json.load est la suivante selon le code source 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 appelle en fait json.loads et l'utilise fp.read()comme premier argument.

Donc, si votre code est:

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

C'est la même chose pour faire ceci:

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

Mais si vous devez spécifier les octets lisant à partir du fichier comme similaires fp.read(10)ou si la chaîne / octets que vous souhaitez désérialiser ne provient pas du fichier, vous devez utiliser json.loads ()

Quant à json.loads (), il désérialise non seulement la chaîne mais également les octets. S'il ss'agit d'octets ou de bytearray, il sera d'abord décodé en chaîne. Vous pouvez également le trouver dans le code source.

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
la source