В чем разница между функциями json.load () и json.loads ()

173

В Python какая разница между json.load()и json.loads()?

Я предполагаю , что нагрузка () функция должна быть использована с файлом объектом (мне нужно таким образом , чтобы использовать менеджер контекста) в то время как нагрузка () функция на пути к файлу в виде строки. Это немного сбивает с толку.

Буква " s " json.loads()означает строку ?

Большое спасибо за ваши ответы!

MMF
источник
1
json.loads(s, *)- Deserialize sstr, bytesили bytearrayэкземпляр , содержащий JSON документ) - docs.python.org/3.6/library/json.html
deceze

Ответы:

160

Да, sобозначает строку. json.loadsФункция не принимает путь к файлу, но содержимое файла в виде строки. Посмотрите документацию по адресу https://docs.python.org/2/library/json.html !

Гис
источник
5
Связанная статья указывает на неправильную версию Python. Вопрос помечен как 2.7.
RvdK
В ответе от @Sufiyan Ghori есть хорошие примеры в дополнение к этому короткому, но конкретному ответу.
Wlad
65

Просто добавлю простой пример к тому, что все объяснили,

json.load ()

json.loadможет десериализовать файл сам, т.е. он принимает fileобъект, например,

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

будет выводить,

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

Если я использую, json.loadsчтобы открыть файл вместо

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

Я получил бы эту ошибку:

Ошибка типа: ожидаемая строка или буфер

json.loads ()

json.loads() десериализовать строку.

Таким образом, для использования json.loadsмне придется передать содержимое файла с помощью read()функции, например,

использование content.read()с json.loads()возвратом содержимого файла,

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

Вывод,

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

Это потому, что тип content.read()является строкой, т.е.<type 'str'>

Если я использую json.load()с content.read(), я получу ошибку,

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

дает,

AttributeError: у объекта 'str' нет атрибута 'read'

Итак, теперь вы знаете json.loadфайл json.loadsдесериализации и десериализацию строки.

Другой пример,

sys.stdinвернуть fileобъект, так что если я это сделаю print(json.load(sys.stdin)), я получу фактические данные JSON,

cat json_data.json | ./test.py

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

Если я хочу использовать json.loads(), я бы сделал print(json.loads(sys.stdin.read()))вместо этого.

Суфиян Гори
источник
4
ЛУЧШИЙ (подробный) ответ. Должен быть проголосован за сопровождающий (короткий) принятый ответ. Вместе они сильны :-)
Wlad
Просто FYI, с Python 3.6.5 with open()и json.loads()возвращает исключение:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Сергей Колодяжный
31

Документация достаточно ясна: 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]]]]]]]])

Десериализовать fp (aread () - поддерживающий файловый объект, содержащий документ JSON) в объект Python, используя эту таблицу преобразования.

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

Десериализовать s (экземпляр str или unicode, содержащий документ JSON) в объект Python, используя эту таблицу преобразования.

Так loadчто для файла, loadsдляstring

RvdK
источник
1
"File like object" против "экземпляра str / unicode". Я не понимаю, что не ясно?
RvdK
7

БЫСТРЫЙ ОТВЕТ (очень упрощенно!)

json.load () принимает файл

json.load () ожидает файл (объект файла) - например, файл, который вы открыли раньше, как указано в filepath 'files/example.json'.


json.loads () принимает STRING

json.loads () ожидает (допустимую) строку JSON - т.е. {"foo": "bar"}


ПРИМЕРЫ

Предполагая, что у вас есть файл example.json с этим содержимым: {"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
источник
Учебник о json.dump/ dumps& json.load/ loads bogotobogo.com/python/…
Wlad
1

Метод json.load () (без «s» в «load») может читать файл напрямую:

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

Метод json.loads () , который используется только для строковых аргументов.

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

Здесь мы можем видеть, что после использования load () принимает строку (тип (str)) в качестве словаря ввода и возврата .

Адитья пати
источник
0

В python3.7.7 определение json.load выглядит следующим образом в соответствии с исходным кодом 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 фактически вызывает json.loads и использует fp.read()в качестве первого аргумента.

Так что, если ваш код:

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

Это то же самое, чтобы сделать это:

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

Но если вам нужно указать байты, считываемые из файла, как и fp.read(10)если строка или байты, которые вы хотите десериализовать, не из файла, вы должны использовать json.loads ()

Что касается json.loads (), он десериализует не только строку, но и байты. Если sэто байты или bytearray, он будет сначала декодирован в строку. Вы также можете найти его в исходном коде.

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

Веньи Ли
источник