问题:json.load()和json.loads()函数有什么区别
在Python中,json.load()
和之间有什么区别json.loads()
?
我猜想load()函数必须与文件对象一起使用(因此,我需要使用上下文管理器),而load()函数将文件路径作为字符串。这有点令人困惑。
字母“ s ” json.loads()
代表字符串吗?
非常感谢你的回答!
In Python, what is the difference between json.load()
and json.loads()
?
I guess that the load() function must be used with a file object (I need thus to use a context manager) while the loads() function take the path to the file as a string. It is a bit confusing.
Does the letter “s” in json.loads()
stand for string?
Thanks a lot for your answers!
回答 0
回答 1
只是在每个人的解释中添加一个简单的例子,
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()))
改为使用。
Just going to add a simple example to what everyone has explained,
json.load()
json.load
can deserialize a file itself i.e. it accepts a file
object, for example,
# 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))
will output,
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
If I use json.loads
to open a file instead,
# you cannot use json.loads on file object
with open("json_data.json", "r") as content:
print(json.loads(content))
I would get this error:
TypeError: expected string or buffer
json.loads()
json.loads()
deserialize string.
So in order to use json.loads
I will have to pass the content of the file using read()
function, for example,
using content.read()
with json.loads()
return content of the file,
with open("json_data.json", "r") as content:
print(json.loads(content.read()))
Output,
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
That’s because type of content.read()
is string, i.e. <type 'str'>
If I use json.load()
with content.read()
, I will get error,
with open("json_data.json", "r") as content:
print(json.load(content.read()))
Gives,
AttributeError: ‘str’ object has no attribute ‘read’
So, now you know json.load
deserialze file and json.loads
deserialize a string.
Another example,
sys.stdin
return file
object, so if i do print(json.load(sys.stdin))
, I will get actual json data,
cat json_data.json | ./test.py
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
If I want to use json.loads()
, I would do print(json.loads(sys.stdin.read()))
instead.
回答 2
文档非常清晰: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
Documentation is quite clear: 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()-supporting file-like object containing a
JSON document) to a Python object using this conversion table.
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
Deserialize s (a str or unicode instance containing a JSON document)
to a Python object using this conversion table.
So load
is for a file, loads
for a string
回答 3
快速解答(非常简化!)
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'
QUICK ANSWER (very simplified!)
json.load() takes a FILE
json.load() expects a file (file object) – e.g. a file you opened before given by filepath like 'files/example.json'
.
json.loads() takes a STRING
json.loads() expects a (valid) JSON string – i.e. {"foo": "bar"}
EXAMPLES
Assuming you have a file example.json with this content: { “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'
回答 4
所述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))作为输入并返回字典之后。
The json.load() method (without “s” in “load”) can read a file directly:
import json
with open('strings.json') as f:
d = json.load(f)
print(d)
json.loads() method, which is used for string arguments only.
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'>
Here , we can see after using loads() takes a string ( type(str) ) as a input and return dictionary.
回答 5
在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')
In python3.7.7, the definition of json.load is as below according to cpython source code:
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 actually calls json.loads and use fp.read()
as the first argument.
So if your code is:
with open (file) as fp:
s = fp.read()
json.loads(s)
It’s the same to do this:
with open (file) as fp:
json.load(fp)
But if you need to specify the bytes reading from the file as like fp.read(10)
or the string/bytes you want to deserialize is not from file, you should use json.loads()
As for json.loads(), it not only deserialize string but also bytes. If s
is bytes or bytearray, it will be decoded to string first. You can also find it in the source code.
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')