Qual é a diferença entre as funções json.load () e json.loads ()

172

Em Python, qual é a diferença entre json.load()e json.loads()?

Eu acho que o load () função deve ser usado com um objeto de arquivo (eu preciso, portanto, usar um gerenciador de contexto), enquanto os () cargas função tomar o caminho para o arquivo como uma string. É um pouco confuso.

A letra " s " json.loads()significa string ?

Muito obrigado por suas respostas!

MMF
fonte
1
json.loads(s, *)- Desserializar s(a str, bytesou bytearrayinstância que contém um documento JSON) - docs.python.org/3.6/library/json.html
deceze

Respostas:

160

Sim, ssignifica string. A json.loadsfunção não pega o caminho do arquivo, mas o conteúdo do arquivo como uma sequência. Veja a documentação em https://docs.python.org/2/library/json.html !

Gijs
fonte
5
O artigo vinculado aponta para a versão incorreta do python. A pergunta está marcada como 2.7.
RvdK 27/09/16
A resposta de @Sufiyan Ghori fornece bons exemplos, além desta resposta curta, mas direta.
Wlad
65

Apenas adicionando um exemplo simples ao que todos explicaram,

json.load ()

json.loadpode desserializar um arquivo em si, ou seja, ele aceita um fileobjeto, por exemplo,

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

irá produzir,

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

Se eu usar json.loadspara abrir um arquivo,

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

Eu receberia este erro:

TypeError: string ou buffer esperado

json.loads ()

json.loads() desserializar string.

Portanto, para usar json.loads, terei que passar o conteúdo do arquivo usando a read()função, por exemplo,

usando content.read()com json.loads()conteúdo de retorno do arquivo,

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

Resultado,

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

Isso content.read()ocorre porque type of is string, ou seja<type 'str'>

Se eu usar json.load()com content.read(), receberei um erro,

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

Dá,

AttributeError: o objeto 'str' não tem atributo 'read'

Então, agora você sabe json.loaddesserializar o arquivo e json.loadsdesserializar uma string.

Outro exemplo,

sys.stdinretornar fileobjeto, então, se eu fizer print(json.load(sys.stdin)), vou obter dados json reais,

cat json_data.json | ./test.py

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

Se eu quiser usar json.loads(), eu faria print(json.loads(sys.stdin.read())).

Sufiyan Ghori
fonte
4
MELHOR (detalhada) resposta. Deve ser votado para acompanhar a resposta aceita (curta). Juntos, eles são fortes :-)
Wlad
Apenas FYI, com Python 3.6.5 a with open()e json.loads()retorna uma exceção:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy
30

A documentação é 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]]]]]]]])

Desserialize fp (um .read () - objeto semelhante a arquivo que suporta um documento JSON) para um objeto Python usando esta tabela de conversão.

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

Desserialize s (uma instância str ou unicode que contém um documento JSON) para um objeto Python usando esta tabela de conversão.

O mesmo loadvale para um arquivo, loadspara umstring

RvdK
fonte
1
"Arquivo como objeto" vs "uma instância str / unicode". Eu não entendo o que não está claro?
RvdK 29/01/19
7

RESPOSTA RÁPIDA (muito simplificado!)

json.load () pega um arquivo

json.load () espera um arquivo (objeto de arquivo) - por exemplo, um arquivo que você abriu antes fornecido pelo caminho do arquivo 'files/example.json'.


json.loads () pega um STRING

json.loads () espera uma string JSON (válida) - ie {"foo": "bar"}


EXEMPLOS

Supondo que você tenha um arquivo example.json com este conteúdo: {"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
fonte
Tutorial sobre json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad
1

O método json.load () (sem "s" em "load") pode ler um arquivo diretamente:

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

O método json.loads () , usado apenas para argumentos de string .

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

Aqui, podemos ver que, após o uso de load (), uma string (type (str)) é usada como dicionário de entrada e retorno .

Aditya patil
fonte
0

No python3.7.7, a definição de json.load é a seguinte, de acordo com o código-fonte 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 realmente chama json.loads e usa fp.read()como o primeiro argumento.

Portanto, se o seu código for:

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

É o mesmo a fazer isso:

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

Mas se você precisar especificar os bytes lidos no arquivo como se fossem iguais fp.read(10)ou a string / bytes que deseja desserializar não for do arquivo, use json.loads ()

Quanto ao json.loads (), ele não apenas desserializa a string, mas também bytes. Se sfor bytes ou bytearray, ele será decodificado para string primeiro. Você também pode encontrá-lo no código fonte.

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
fonte