Sự khác biệt giữa các hàm json.load () và json.loads () là gì


172

Trong Python, sự khác biệt giữa json.load()và là json.loads()gì?

Tôi đoán rằng hàm load () phải được sử dụng với một đối tượng tệp (do đó tôi cần sử dụng trình quản lý bối cảnh) trong khi hàm load () lấy đường dẫn đến tệp dưới dạng chuỗi. Nó hơi khó hiểu.

Chữ " s " có json.loads()đứng trong chuỗi không?

Cảm ơn rất nhiều cho câu trả lời của bạn!


1
json.loads(s, *)- Deserialize s(một str, byteshoặc bytearraydụ chứa một tài liệu JSON) - docs.python.org/3.6/library/json.html
deceze

Câu trả lời:


160

Vâng, slà viết tắt của chuỗi. Các json.loadschức năng không đi theo con đường tập tin, nhưng nội dung tập tin như là một chuỗi. Xem tài liệu tại https://docs.python.org/2/l Library / json.html !


5
Liên kết bài viết chỉ đến phiên bản python sai. Câu hỏi được gắn thẻ là 2.7.
RvdK

câu trả lời từ @Sufiyan Ghori cung cấp các ví dụ hay ngoài câu trả lời ngắn gọn này.
Wlad

65

Chỉ cần thêm một ví dụ đơn giản vào những gì mọi người đã giải thích,

json.load ()

json.loadcó thể giải tuần tự hóa một tập tin, ví dụ như nó chấp nhận một fileđối tượng

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

sẽ đầu ra,

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

Nếu tôi sử dụng json.loadsđể mở một tập tin thay thế,

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

Tôi sẽ nhận được lỗi này:

TypeError: chuỗi hoặc bộ đệm dự kiến

json.loads ()

json.loads() chuỗi khử lưu huỳnh.

Vì vậy, để sử dụng, json.loadstôi sẽ phải truyền nội dung của tệp bằng read()hàm, ví dụ:

sử dụng content.read()với json.loads()nội dung trả về của tệp,

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

Đầu ra,

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

Đó là bởi vì loại content.read()là chuỗi, tức là<type 'str'>

Nếu tôi sử dụng json.load()với content.read(), tôi sẽ gặp lỗi,

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

Cho,

AttributionError: đối tượng 'str' không có thuộc tính 'read'

Vì vậy, bây giờ bạn biết json.loadtập tin json.loadsdeserialze và deserialize một chuỗi.

Một vi dụ khac,

sys.stdinfileĐối tượng trả về , vì vậy nếu tôi làm print(json.load(sys.stdin)), tôi sẽ nhận được dữ liệu json thực tế,

cat json_data.json | ./test.py

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

Nếu tôi muốn sử dụng json.loads(), tôi sẽ làm print(json.loads(sys.stdin.read()))thay thế.


4
Câu trả lời TỐT NHẤT (chi tiết). Nên bỏ phiếu để đi kèm (ngắn) câu trả lời được chấp nhận. Họ cùng nhau mạnh mẽ :-)
Wlad

Chỉ cần FYI, với Python 3.6.5 with open()json.loads()trả về một ngoại lệ:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy 28/12/19

30

Tài liệu khá rõ ràng: https://docs.python.org/2/l Library / json.html

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

Deserialize fp (a .read () - hỗ trợ đối tượng giống như tệp có chứa tài liệu JSON) cho đối tượng Python bằng bảng chuyển đổi này.

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

Deserialize s (một ví dụ str hoặc unicode chứa tài liệu JSON) cho đối tượng Python bằng bảng chuyển đổi này.

Vì vậy, loadlà cho một tập tin, loadscho mộtstring


1
"Tệp giống như đối tượng" so với "một ví dụ str / unicode". Tôi không hiểu những gì không rõ ràng?
RvdK

7

TRẢ LỜI NHANH CHÓNG (rất đơn giản!)

json.load () mất một tập tin

json.load () mong đợi một tệp (đối tượng tệp) - ví dụ: tệp bạn đã mở trước khi được cung cấp bởi filepath như thế nào 'files/example.json'.


json.loads () mất một chuỗi

json.loads () mong đợi một chuỗi JSON (hợp lệ) - tức là {"foo": "bar"}


VÍ DỤ

Giả sử bạn có tệp example.json với nội dung này: {"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'

Hướng dẫn về json.dump/ dumps& json.load/ loads bogotobogo.com/python/ từ
Wlad

1

Phương thức json.load () (không có "s" trong "load") có thể đọc tệp trực tiếp:

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

Phương thức json.loads () , chỉ được sử dụng cho các đối số chuỗi .

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

Ở đây, chúng ta có thể thấy sau khi sử dụng load () lấy một chuỗi (loại (str)) làm từ điển đầu vào và trả về .


0

Trong python3.7.7, định nghĩa của json.load như dưới đây theo mã nguồn 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 thực sự gọi json.loads và sử dụng fp.read() làm đối số đầu tiên.

Vì vậy, nếu mã của bạn là:

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

Điều này giống nhau để làm điều này:

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

Nhưng nếu bạn cần chỉ định các byte đọc từ tệp như fp.read(10) hoặc chuỗi / byte bạn muốn giải tuần tự không phải từ tệp, bạn nên sử dụng json.loads ()

Đối với json.loads (), nó không chỉ giải tuần tự chuỗi mà còn cả byte. Nếu slà byte hoặc bytearray, nó sẽ được giải mã thành chuỗi đầu tiên. Bạn cũng có thể tìm thấy nó trong mã nguồn.

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')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.