json.load()和json.loads()函数有什么区别


172

在Python中,json.load()和之间有什么区别json.loads()

我猜想load()函数必须与文件对象一起使用(因此,我需要使用上下文管理器),而load()函数将文件路径作为字符串。这有点令人困惑。

字母“ sjson.loads()代表字符串吗?

非常感谢你的回答!


1
json.loads(s, *)-反序列化s(一个strbytesbytearray含有JSON文档实例) - docs.python.org/3.6/library/json.html
deceze

Answers:


160

是的,s代表字符串。该json.loads函数不采用文件路径,而是将文件内容作为字符串。查看位于https://docs.python.org/2/library/json.html的文档!


5
链接的文章指向错误的python版本。问题被标记为2.7。
RvdK

@Sufiyan Ghori的答案除了简短但要点之外,还提供了很好的示例。
弗拉德

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

仅供参考,使用Python 3.6.5 with open()json.loads()返回异常:TypeError: the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'
Sergiy Kolodyazhnyy

30

文档非常清晰: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(支持.read()的包含JSON文档的类似文件的对象)反序列化为Python对象。

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

使用此转换表将s(包含JSON文档的str或unicode实例)反序列化为Python对象。

所以load是一个文件,loads一个string


1
“像文件一样的对象”与“一个str / unicode实例”。我不明白还不清楚吗?
RvdK

7

快速解答(非常简化!)

json.load()需要一个文件

json.load()需要一个文件(文件对象),例如,您在文件路径(如)给定之前打开的文件'files/example.json'


json.loads()需要一个STRING

json.loads()需要一个(有效)JSON字符串-即 {"foo": "bar"}


例子

假设您有一个文件example.json,其内容如下:{“ key_1”: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/ dumpsjson.load/ loads bogotobogo.com/python/...
Wlad

1

所述json.load()方法(无“S”中的“负荷”)可直接读取的文件:

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()将字符串(type(str))作为输入并返回字典之后


0

在python3.7.7中,根据cpython源代码,json.load的定义如下:

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为bytes或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')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.