What is the difference between json.load() and json.loads() functions

前端 未结 6 749
天涯浪人
天涯浪人 2020-11-29 16:36

In Python, what is the difference between json.load() and json.loads()?

I guess that the load() function must be used with a file

相关标签:
6条回答
  • 2020-11-29 16:44

    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')
    
    
    0 讨论(0)
  • 2020-11-29 16:49

    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.

    0 讨论(0)
  • 2020-11-29 16:51

    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'
    
    0 讨论(0)
  • 2020-11-29 16:52

    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 at https://docs.python.org/2/library/json.html!

    0 讨论(0)
  • 2020-11-29 17:01

    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

    0 讨论(0)
  • 2020-11-29 17:03

    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.

    0 讨论(0)
提交回复
热议问题