¿Cuál es la diferencia entre las funciones json.load () y json.loads ()

173

En Python, ¿cuál es la diferencia entre json.load()y json.loads()?

Supongo que la carga () la función se debe utilizar con un objeto de archivo (Necesito por lo tanto utilizar un gestor de contexto), mientras que las () cargas de función toman la ruta del archivo como una cadena. Es un poco confuso.

¿La letra " s " enjson.loads() significa cadena ?

¡Muchas gracias por sus respuestas!

MMF
fuente
1
json.loads(s, *)- Deserialize s(a str, byteso bytearrayejemplo que contiene un documento JSON) - docs.python.org/3.6/library/json.html
deceze

Respuestas:

160

Sí, ssignifica cuerda. La json.loadsfunción no toma la ruta del archivo, sino el contenido del archivo como una cadena. ¡Mira la documentación en https://docs.python.org/2/library/json.html !

Gijs
fuente
55
El artículo vinculado apunta a la versión incorrecta de Python. La pregunta está etiquetada como 2.7.
RvdK
La respuesta de @Sufiyan Ghori proporciona buenos ejemplos además de esta respuesta breve pero directa.
Wlad
65

Solo voy a agregar un ejemplo simple a lo que todos han explicado,

json.load ()

json.loadpuede deserializar un archivo en sí mismo, es decir, acepta un fileobjeto, por ejemplo,

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

dará salida,

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

Si uso json.loadspara abrir un archivo en su lugar,

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

Me daría este error:

TypeError: cadena esperada o buffer

json.loads ()

json.loads() deserializar cadena.

Entonces, para usarlo json.loads, tendré que pasar el contenido del archivo usandoread() función, por ejemplo,

utilizando content.read()con el json.loads()contenido de retorno del archivo,

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

Salida,

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

Eso es porque tipo de content.read() es una cadena, es decir<type 'str'>

Si uso json.load()con content.read(), obtendré un error,

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

Da,

AttributeError: el objeto 'str' no tiene el atributo 'read'

Entonces, ahora sabes el json.loadarchivo deserialze yjson.loads deserializar una cadena.

Otro ejemplo,

sys.stdindevolver fileobjeto, así que si lo hago print(json.load(sys.stdin)), obtendré datos json reales,

cat json_data.json | ./test.py

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

Si quiero usar json.loads(), lo haría en su print(json.loads(sys.stdin.read()))lugar.

Sufiyan Ghori
fuente
44
MEJOR respuesta (detallada). Debe ser votado para acompañar la respuesta (corta) aceptada. Juntos son fuertes :-)
Wlad
Solo para tu información, con Python 3.6.5 with open()y json.loads()devuelve una excepción:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy
30

La documentación es bastante clara: 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]]]]]]]])

Deserialice fp (un .read () - compatible con un objeto similar a un archivo que contiene un documento JSON) a un objeto Python usando esta tabla de conversión.

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

Deserialice s (una instancia str o unicode que contiene un documento JSON) a un objeto Python usando esta tabla de conversión.

Así loades para un archivo, loadspara unstring

RvdK
fuente
1
"Archivo como objeto" frente a "una instancia str / unicode". No entiendo lo que no está claro?
RvdK
7

RESPUESTA RÁPIDA (¡muy simplificado!)

json.load () toma un ARCHIVO

json.load () espera un archivo (objeto de archivo), por ejemplo, un archivo que abrió antes dado por filepath como 'files/example.json'.


json.loads () toma un STRING

json.loads () espera una cadena JSON (válida), es decir {"foo": "bar"}


EJEMPLOS

Suponiendo que tiene un archivo example.json con este contenido: {"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
fuente
Tutorial sobre json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad
1

El método json.load () (sin "s" en "load") puede leer un archivo directamente:

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

Método json.loads () , que se usa solo para argumentos de cadena .

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

Aquí, podemos ver que después de usar cargas () toma una cadena (tipo (cadena)) como un diccionario de entrada y retorno .

Aditya patil
fuente
0

En python3.7.7, la definición de json.load es la siguiente según el código fuente de 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 en realidad llama a json.loads y se usa fp.read()como primer argumento.

Entonces, si su código es:

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

Es lo mismo hacer esto:

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

Pero si necesita especificar la lectura de bytes del archivo como like fp.read(10)o la cadena / bytes que desea deserializar no es del archivo, debe usar json.loads ()

En cuanto a json.loads (), no solo deserializa la cadena sino también los bytes. Si ses bytes o bytearray, primero se decodificará en cadena. También puedes encontrarlo en el código fuente.

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
fuente