Яка різниця між функціями json.load () та json.loads ()


173

У Python в чому різниця між json.load()і json.loads()?

Я припускаю , що навантаження () функція повинна бути використана з файлом об'єктом (мені потрібно таким чином , щоб використовувати менеджер контексту) в той час як навантаження () функція на шляху до файлу у вигляді рядка. Це трохи заплутано.

Чи відповідає буква " s " json.loads()для рядка ?

Дякую за відповіді!


1
json.loads(s, *)- Deserialize s(а str, 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
Пов'язана стаття вказує на неправильну версію пітона. Питання позначено як 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))

Я отримаю цю помилку:

TypeError: очікуваний рядок або буфер

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.loadsdeserialze і деріаріалізуйте рядок.

Інший приклад,

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 (a .read () - підтримує файл-об’єкт, що містить документ 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


1
"Файл як об'єкт" vs "екземпляр str / unicode". Я не розумію, що не зрозуміло?
— RvdK

7

ШВИДКИЙ ВІДПОВІДЬ (дуже спрощено!)

json.load () приймає FILE

json.load () очікує файл (файл-об’єкт) - наприклад, файл, який ви відкрили раніше, заданий файловим шляхом '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'

Підручник про 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це байти або байт-масив, він спочатку буде декодований до рядка. Ви також можете знайти його у вихідному коді.

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')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.