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

06odsfpq  于 2023-03-31  发布在  其他
关注(0)|答案(6)|浏览(214)

在Python中,json.load()json.loads()有什么区别?
我猜 load() 函数必须与文件对象一起使用(因此我需要使用上下文管理器),而 loads() 函数将文件的路径作为字符串。这有点令人困惑。
json.loads()中的字母“s”是否代表string
非常感谢您的回答!

4ngedf3f

4ngedf3f1#

是的,s代表字符串。json.loads函数不接受文件路径,而是将文件内容作为字符串。请看the documentation

uqxowvwt

uqxowvwt2#

在大家解释的基础上再加一个简单的例子,

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

给予,
属性错误:“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()))

kqlmhetl

kqlmhetl3#

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

ca1c2owp

ca1c2owp4#

快速解答(非常简单!)

json.load()获取FILE

json.load()需要一个文件(文件对象)--例如,你之前打开的文件,由filepath给出,比如'files/example.json'

json.loads()接受一个STRING

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

示例

假设你有一个文件example.json,内容如下:{“key_1”:1,“key_2”:“foo”,“Key_3”:空}

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

irtuqstp5#

在python3.7.7中,根据cpython source code,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)

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(),它不仅反序列化string,还反序列化bytes。如果s是bytes或bytearray,则会先解码为string。您也可以在源代码中找到。

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

zpgglvta6#

区别在于JSON文本的源
load()期望从一个类似文件的对象中获取文本json.loads()期望从一个字符串对象中获取文本
假设您有一个包含以下内容的文件(json.txt

[ {"name": "Fred", "age": 32}, {"name": "Bob", "age": 21 } ]

现在学习以下内容:

>>> import json 
>>> with open("json.txt") as f:
      j1 = json.load(f) 
>>> j1 
[{u'age': 32, u'name': u'Fred'}, {u'age': 21, u'name': u'Bob'}]

现在使用字符串

>>> with open("json.txt") as f: 
  txt = f.read()  
>>> txt 
'[ { "name": "Fred", "age": 32}, {"name": "Bob", "age": 21 } ]\n\n' 
>>> json.loads(txt) 
[{u'age': 32, u'name': u'Fred'}, {u'age': 21, u'name': u'Bob'}]

在第一部分中,我们使用json.load()直接读取文件,在section部分中,我们首先将文件的内容读入一个字符串变量,然后将该变量传递给json.loads()
同样的关系也适用于json.dump()和json.dumps()

相关问题