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!


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 !


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())).


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


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'

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 .


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')
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.