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?
Best Answer
Yes, s
stands for string. The json.loads
function does not take the file path, but the file contents as a string. Look at the documentation.
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.loadwith 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 objectwith 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.
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 aJSON 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
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 loadsTypeError: 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 loadreturn loads(fp.read(),AttributeError: 'str' object has no attribute 'read'
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`` instancecontaining 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')
The difference is in the source of the JSON text
json.load() expects to get the text from a file-like objectjson.loads() expects to get its text from a string object
Assume you have a file (json.txt) with the following contents
[ {"name": "Fred", "age": 32}, {"name": "Bob", "age": 21 } ]
Now study the following:
>>> 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'}]
Now using strings
>>> 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'}]
In the first part, we read the file directly using json.load(). In the section part, we first read the file’s contents into a string variable, then pass that variable to json.loads()
The same relationship holds for json.dump() and json.dumps()