Jaka jest różnica między funkcjami json.load () i json.loads ()


172

W Pythonie, jaka jest różnica między json.load()i json.loads()?

Myślę, że obciążenie () funkcja musi być używany z obiektu pliku (Muszę zatem, aby użyć menedżera kontekstowe), natomiast () ładuje funkcyjne wziąć ścieżkę do pliku jako ciąg znaków. To trochę zagmatwane.

Czy litera „ s ” json.loads()oznacza ciąg ?

Wielkie dzięki za odpowiedzi!


1
json.loads(s, *)- Cofnięcie s(a str, byteslub bytearrayprzykład zawierającego dokument JSON) - docs.python.org/3.6/library/json.html
— deceze

Odpowiedzi:


160

Tak, soznacza string. json.loadsFunkcja nie bierze ścieżkę pliku, ale zawartość pliku jako ciąg. Zajrzyj do dokumentacji na https://docs.python.org/2/library/json.html !


5
Powiązany artykuł wskazuje na niewłaściwą wersję Pythona. Pytanie jest oznaczone jako 2.7.
— RvdK

odpowiedź od @Sufiyan Ghori zawiera ładne przykłady oprócz tej krótkiej, ale rzeczowej odpowiedzi.
— Wład

65

Dodam tylko prosty przykład do tego, co wszyscy wyjaśnili,

json.load ()

json.loadmoże sam deserializować plik, tzn. akceptuje fileobiekt, na przykład

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

wyjdzie,

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

Jeśli json.loadszamiast tego użyję do otwarcia pliku,

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

Otrzymałbym ten błąd:

TypeError: oczekiwany ciąg lub bufor

json.loads ()

json.loads() ciąg deserializacji.

Żeby więc skorzystać json.loadsbędę musiał przekazać zawartość pliku za pomocą read()funkcji np.

korzystanie content.read()ze json.loads()zwrotem zawartości pliku,

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

Wynik,

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

Dzieje się tak, ponieważ typ content.read()to string, tj<type 'str'>

Jeśli używam json.load()z content.read(), otrzymam błąd,

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

Daje,

AttributeError: obiekt „str” nie ma atrybutu „odczyt”

Więc teraz znasz json.loadplik json.loadsdeserialze i deserializujesz ciąg.

Inny przykład,

sys.stdinzwraca fileobiekt, więc jeśli to zrobię print(json.load(sys.stdin)), otrzymam aktualne dane json,

cat json_data.json | ./test.py

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

Jeśli chcę użyć json.loads(), zrobiłbym to print(json.loads(sys.stdin.read()))zamiast tego.


4
NAJLEPSZA (szczegółowa) odpowiedź. Powinien zostać poddany głosowaniu pozytywnemu, aby dołączyć do (krótkiej) zaakceptowanej odpowiedzi. Razem są mocni :-)
— Wład

Do Twojej wiadomości, z Pythonem 3.6.5 with open()i json.loads()zwraca wyjątek:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
— Sergiy Kolodyazhnyy

30

Dokumentacja jest dość przejrzysta: 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]]]]]]]])

Deserialize fp (a .read () - obsługujący obiekt podobny do pliku zawierający dokument JSON) do obiektu Pythona przy użyciu tej tabeli konwersji.

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

Deserializuj s (instancję str lub Unicode zawierającą dokument JSON) do obiektu Python przy użyciu tej tabeli konwersji.

Tak loadjest w przypadku pliku, loadsastring


1
„Obiekt podobny do pliku” a „instancja str / unicode”. Nie rozumiem, co nie jest jasne?
— RvdK

7

SZYBKA ODPOWIEDŹ (bardzo uproszczona!)

json.load () pobiera PLIK

json.load () oczekuje pliku (obiektu pliku) - np. pliku, który otworzyłeś wcześniej, podanego przez ścieżkę pliku, na przykład 'files/example.json'.


json.loads () przyjmuje STRING

json.loads () oczekuje (prawidłowego) ciągu JSON - tj {"foo": "bar"}


PRZYKŁADY

Zakładając, że masz plik example.json z taką zawartością: {"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'

Samouczek o json.dump/ dumps& json.load/ loads bogotobogo.com/python/ ...
— Wład

1

Metoda json.load () (bez „s” w „load”) może bezpośrednio odczytać plik:

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

json.loads () , która jest używana tylko dla argumentów łańcuchowych .

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

Tutaj widzimy, że po użyciu load () przyjmuje ciąg znaków (type (str)) jako słownik wejściowy i zwrotny .


0

W pythonie3.7.7 definicja json.load jest następująca, zgodnie z kodem źródłowym 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 faktycznie wywołuje json.loads i używa go fp.read()jako pierwszego argumentu.

Więc jeśli twój kod to:

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

Robi się to tak samo:

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

Ale jeśli chcesz określić bajty odczytywane z pliku jako podobne fp.read(10)lub ciąg / bajty, które chcesz deserializować, nie pochodzą z pliku, powinieneś użyć json.loads ()

Jeśli chodzi o json.loads (), nie tylko deserializuje ciąg, ale także bajty. Jeśli sto bajty lub bytearray, zostanie najpierw zdekodowany na łańcuch. Możesz go również znaleźć w kodzie źródłowym.

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')
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.