carllecat carllecat - 1 year ago 264
JSON Question

JSON Using Python

I tried running this code and get error:

Traceback (most recent call last):
File "/Users/ccharest/Desktop/PCC/", line 7, in <module>
username = json.load(f_obj)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/", line 319, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

What is wrong with this block of code?

import json

filename = 'username2.json'

with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What is your name? ")
username = username.title()
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back {}!".format(username))

print("Welcome back {}!".format(username))

As suggested by some, I changed the filename from "usernam2.json" to "uname.json" and it worked... Why would using filename "username2.json" trigger the error???

As suggested by Alexander Huszagh, the file "username2.json" was created, but was empty.I deleted the file "username2.json" and ran the script again and it worked fine.

Answer Source

As the comments suggest above, your code is fine. The contents of your file, however, are almost certainly empty or not JSON. A quick proof of concept:

In [1]: import json

In [2]: json.loads("a")
JSONDecodeError                           Traceback (most recent call last)
<ipython-input-2-98479bdf8b77> in <module>()
----> 1 json.loads("")

/usr/lib/python3.5/json/ in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    317             parse_int is None and parse_float is None and
    318             parse_constant is None and object_pairs_hook is None and not kw):
--> 319         return _default_decoder.decode(s)
    320     if cls is None:
    321         cls = JSONDecoder

/usr/lib/python3.5/json/ in decode(self, s, _w)
    338         """
--> 339         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340         end = _w(s, end).end()
    341         if end != len(s):

/usr/lib/python3.5/json/ in raw_decode(self, s, idx)
    355             obj, end = self.scan_once(s, idx)
    356         except StopIteration as err:
--> 357             raise JSONDecodeError("Expecting value", s, err.value) from None
    358         return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Are you sure you actually have JSON data in your file?

If you have any recognized JSON structure, but it is not entirely complete, such as the following, it will raise another decode error:

In [4]: json.loads('{"a": "b"')

JSONDecodeError: Expecting ',' delimiter: line 1 column 10 (char 9)

If you want to specifically handle the null file example, you can do:

import json
path = "path/to/file.json"
except json.JsonDecodeError as error:
    if (error.msg.startswith("Expecting") and error.pos == 0):
        # ignore the error, empty file, or non-JSON grammar, so it was expecting a JSON element but found none
        # if you would like to differentiate empty files from non-JSON files, use `os.stat` on the path, or pass in a file handle as `file` and use `file.tell()` to check if it returns 0
        # another grammar issue