从一些复杂的JSON文件中加载数据的Python代码:
with open(filename, "r") as f:
data = json.loads(f.read())
(注意:最好的代码版本应该是:
with open(filename, "r") as f:
data = json.load(f)
但两者都表现出类似的行为)
对于许多类型的JSON错误(缺少分隔符,字符串中的错误反斜杠等),这会打印一条很有用的消息,其中包含发现JSON错误的行号和列号。
但是,对于其他类型的JSON错误(包括经典的“在列表中的最后一项上使用逗号”,还有其他内容,如大写true / false),Python的输出只是:
Traceback (most recent call last):
File "myfile.py", line 8, in myfunction
config = json.loads(f.read())
File "c:\python27\lib\json\__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "c:\python27\lib\json\decoder.py", line 360, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "c:\python27\lib\json\decoder.py", line 378, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
对于那种类型的ValueError,你如何让Python告诉你JSON文件中的错误在哪里?
答案 0 :(得分:164)
我发现simplejson
模块在内置json
模块含糊不清的许多情况下会出现更多描述性错误。例如,对于在列表中的最后一项之后使用逗号的情况:
json.loads('[1,2,]')
....
ValueError: No JSON object could be decoded
这不是很具描述性。与simplejson
:
simplejson.loads('[1,2,]')
...
simplejson.decoder.JSONDecodeError: Expecting object: line 1 column 5 (char 5)
好多了!同样,对于其他常见错误,例如大写True
。
答案 1 :(得分:14)
你无法让python告诉你JSON不正确的地方。您需要在this
之类的地方使用linter这将显示您尝试解码的JSON中的错误。
答案 2 :(得分:7)
您可以尝试在此处找到的rson库:http://code.google.com/p/rson/。我也在PYPI:https://pypi.python.org/pypi/rson/0.9,所以你可以使用easy_install或pip来获取它。
给出tom的例子:
>>> rson.loads('[1,2,]')
...
rson.base.tokenizer.RSONDecodeError: Unexpected trailing comma: line 1, column 6, text ']'
RSON旨在成为JSON的超集,因此它可以解析JSON文件。它还有一个替代语法,很多更好,人类可以查看和编辑。我对输入文件使用了很多。
至于布尔值的大写:看起来rson读错了大写的布尔值作为字符串。
>>> rson.loads('[true,False]')
[True, u'False']
答案 3 :(得分:4)
我有类似的问题,这是由于单引号。 JSON标准(http://json.org)仅讨论使用双引号,因此必须是python json
库仅支持双引号。
答案 4 :(得分:2)
对于我这个问题的特定版本,我继续搜索load_json_file(path)
文件中packaging.py
的函数声明,然后将print
行走私到其中:
def load_json_file(path):
data = open(path, 'r').read()
print data
try:
return Bunch(json.loads(data))
except ValueError, e:
raise MalformedJsonFileError('%s when reading "%s"' % (str(e),
path))
这样它会在输入try-catch之前打印json文件的内容,这样 - 即使我几乎没有Python知识 - 我能够快速找出为什么我的配置无法读取json文件。
(因为我已经设置了我的文本编辑器来编写UTF-8 BOM ...愚蠢)
刚才提到这一点,因为虽然对OP的具体问题可能不是一个好的答案,但这是确定一个非常压迫的bug的来源的一种相当快速的方法。我打赌很多人会偶然发现这篇文章正在为MalformedJsonFileError: No JSON object could be decoded when reading …
搜索更详细的解决方案。这可能对他们有所帮助。
答案 5 :(得分:2)
我遇到了类似的问题,这是我的代码:
json_file=json.dumps(pyJson)
file = open("list.json",'w')
file.write(json_file)
json_file = open("list.json","r")
json_decoded = json.load(json_file)
print json_decoded
问题是我忘了file.close()
我做了它并解决了问题。
答案 6 :(得分:1)
对我来说,我的json文件很大,在python中使用常见的json
时会出现上述错误。
通过simplejson
安装sudo pip install simplejson
后。
然后我解决了。
import json
import simplejson
def test_parse_json():
f_path = '/home/hello/_data.json'
with open(f_path) as f:
# j_data = json.load(f) # ValueError: No JSON object could be decoded
j_data = simplejson.load(f) # right
lst_img = j_data['images']['image']
print lst_img[0]
if __name__ == '__main__':
test_parse_json()
答案 7 :(得分:0)
接受的答案是解决问题的最简单方法。但是,如果由于您的公司政策而不允许您安装simplejson,我建议在下面的解决方案中修复“在列表中的最后一项上使用逗号”的特定问题“:
创建一个子类“JSONLintCheck”以继承自“JSONDecoder”类,并覆盖类“JSONDecoder”的 init 方法,如下所示:
def __init__(self, encoding=None, object_hook=None, parse_float=None,parse_int=None, parse_constant=None, strict=True,object_pairs_hook=None)
super(JSONLintCheck,self).__init__(encoding=None, object_hook=None, parse_float=None,parse_int=None, parse_constant=None, strict=True,object_pairs_hook=None)
self.scan_once = make_scanner(self)
1 #!/usr/bin/env python
2 from json import JSONDecoder
3 from json import decoder
4 import re
5
6 NUMBER_RE = re.compile(
7 r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
8 (re.VERBOSE | re.MULTILINE | re.DOTALL))
9
10 def py_make_scanner(context):
11 parse_object = context.parse_object
12 parse_array = context.parse_array
13 parse_string = context.parse_string
14 match_number = NUMBER_RE.match
15 encoding = context.encoding
16 strict = context.strict
17 parse_float = context.parse_float
18 parse_int = context.parse_int
19 parse_constant = context.parse_constant
20 object_hook = context.object_hook
21 object_pairs_hook = context.object_pairs_hook
22
23 def _scan_once(string, idx):
24 try:
25 nextchar = string[idx]
26 except IndexError:
27 raise ValueError(decoder.errmsg("Could not get the next character",string,idx))
28 #raise StopIteration
29
30 if nextchar == '"':
31 return parse_string(string, idx + 1, encoding, strict)
32 elif nextchar == '{':
33 return parse_object((string, idx + 1), encoding, strict,
34 _scan_once, object_hook, object_pairs_hook)
35 elif nextchar == '[':
36 return parse_array((string, idx + 1), _scan_once)
37 elif nextchar == 'n' and string[idx:idx + 4] == 'null':
38 return None, idx + 4
39 elif nextchar == 't' and string[idx:idx + 4] == 'true':
40 return True, idx + 4
41 elif nextchar == 'f' and string[idx:idx + 5] == 'false':
42 return False, idx + 5
43
44 m = match_number(string, idx)
45 if m is not None:
46 integer, frac, exp = m.groups()
47 if frac or exp:
48 res = parse_float(integer + (frac or '') + (exp or ''))
49 else:
50 res = parse_int(integer)
51 return res, m.end()
52 elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
53 return parse_constant('NaN'), idx + 3
54 elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
55 return parse_constant('Infinity'), idx + 8
56 elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
57 return parse_constant('-Infinity'), idx + 9
58 else:
59 #raise StopIteration # Here is where needs modification
60 raise ValueError(decoder.errmsg("Expecting propert name enclosed in double quotes",string,idx))
61 return _scan_once
62
63 make_scanner = py_make_scanner
答案 8 :(得分:0)
只是遇到了相同的问题,在我的情况下,该问题与文件开头的BOM
(字节顺序标记)有关。
json.tool
将拒绝处理甚至是空文件(只是花括号),直到我删除了UTF BOM标记。
我所做的是:
set nobomb
)这解决了json.tool的问题。希望这会有所帮助!
答案 9 :(得分:0)
创建文件时。而不是创建内容为空的文件。替换为:
json.dump({}, file)
答案 10 :(得分:-3)
你可以使用cjson,声称它比pure-python实现快250倍,因为你有“一些很复杂的JSON文件”,你可能需要多次运行它(解码器)失败并报告他们遇到的第一个错误。