Python 显示比“无法解码 JSON 对象”更好的错误消息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14899506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Displaying better error message than "No JSON object could be decoded"
提问by OJW
Python code to load data from some long complicated JSON file:
从一些长而复杂的 JSON 文件加载数据的 Python 代码:
with open(filename, "r") as f:
data = json.loads(f.read())
(note: the best code version should be:
(注意:最好的代码版本应该是:
with open(filename, "r") as f:
data = json.load(f)
but both exhibit similar behavior)
但两者都表现出相似的行为)
For many types of JSON error (missing delimiters, incorrect backslashes in strings, etc), this prints a nice helpful message containing the line and column number where the JSON error was found.
对于许多类型的 JSON 错误(缺少分隔符、字符串中的反斜杠不正确等),这会打印出一个很好的有用消息,其中包含发现 JSON 错误的行号和列号。
However, for other types of JSON error (including the classic "using comma on the last item in a list", but also other things like capitalising true/false), Python's output is just:
但是,对于其他类型的 JSON 错误(包括经典的“在列表的最后一项上使用逗号”,以及其他诸如大写真/假之类的事情),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
For that type of ValueError, how do you get Python to tell you where is the error in the JSON file?
对于这种类型的 ValueError,您如何让 Python 告诉您 JSON 文件中的错误在哪里?
采纳答案by tom
I've found that the simplejsonmodule gives more descriptive errors in many cases where the built-in jsonmodule is vague. For instance, for the case of having a comma after the last item in a list:
我发现simplejson在内置json模块含糊不清的许多情况下,该模块会给出更多描述性错误。例如,对于列表中最后一项后有逗号的情况:
json.loads('[1,2,]')
....
ValueError: No JSON object could be decoded
which is not very descriptive. The same operation with simplejson:
这不是很有描述性。相同的操作simplejson:
simplejson.loads('[1,2,]')
...
simplejson.decoder.JSONDecodeError: Expecting object: line 1 column 5 (char 5)
Much better! Likewise for other common errors like capitalizing True.
好多了!同样对于其他常见错误,如大写True。
回答by myusuf3
回答by Brad Campbell
You could try the rson library found here: http://code.google.com/p/rson/. I it also up on PYPI: https://pypi.python.org/pypi/rson/0.9so you can use easy_install or pip to get it.
您可以尝试在此处找到的 rson 库:http: //code.google.com/p/rson/。我也在 PYPI 上:https://pypi.python.org/pypi/rson/0.9所以你可以使用 easy_install 或 pip 来获取它。
for the example given by tom:
对于汤姆给出的例子:
>>> rson.loads('[1,2,]')
...
rson.base.tokenizer.RSONDecodeError: Unexpected trailing comma: line 1, column 6, text ']'
RSON is a designed to be a superset of JSON, so it can parse JSON files. It also has an alternate syntax which is muchnicer for humans to look at and edit. I use it quite a bit for input files.
RSON 被设计为 JSON 的超集,因此它可以解析 JSON 文件。它还具有替代语法,这对于人类查看和编辑来说要好得多。我经常将它用于输入文件。
As for the capitalizing of boolean values: it appears that rson reads incorrectly capitalized booleans as strings.
至于布尔值的大写:似乎 rson 将错误的大写布尔值读取为字符串。
>>> rson.loads('[true,False]')
[True, u'False']
回答by yahe
You could use cjson, that claims to be up to 250 times faster than pure-python implementations, given that you have "some long complicated JSON file" and you will probably need to run it several times (decoders fail and report the first error they encounter only).
你可以使用cjson,它声称比纯 python 实现快 250 倍,因为你有“一些长而复杂的 JSON 文件”,你可能需要多次运行它(解码器失败并报告第一个错误)只遇到)。
回答by Knight Samar
I had a similar problem and it was due to singlequotes. The JSON standard(http://json.org) talks only about using double quotesso it must be that the python jsonlibrary supports only double quotes.
我有一个类似的问题,这是由于单引号。JSON 标准 ( http://json.org) 只讨论使用双引号,所以必须是 pythonjson库只支持双引号。
回答by WoodrowShigeru
For my particular version of this problem, I went ahead and searched the function declaration of load_json_file(path)within the packaging.pyfile, then smuggled a printline into it:
对于我这个问题的特别版本,我继续搜索的函数声明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))
That way it would print the content of the json file before entering the try-catch, and that way – even with my barely existing Python knowledge – I was able to quickly figure out why my configuration couldn't read the json file.
(It was because I had set up my text editor to write a UTF-8 BOM … stupid)
这样它会在进入 try-catch 之前打印 json 文件的内容,这样——即使我几乎没有 Python 知识——我也能够快速找出为什么我的配置无法读取 json 文件。
(那是因为我已经设置了我的文本编辑器来编写一个 UTF-8 BOM ......愚蠢)
Just mentioning this because, while maybe not a good answer to the OP's specific problem, this was a rather quick method in determining the source of a very oppressing bug. And I bet that many people will stumble upon this article who are searching a more verbose solution for a MalformedJsonFileError: No JSON object could be decoded when reading …. So that might help them.
之所以提到这一点,是因为虽然可能不是对 OP 特定问题的一个很好的答案,但这是确定一个非常令人沮丧的错误来源的一种相当快速的方法。我敢打赌,很多人会偶然发现这篇文章,他们正在为MalformedJsonFileError: No JSON object could be decoded when reading …. 所以这可能对他们有帮助。
回答by Habib Kazemi
I had a similar problem this was my code:
我有一个类似的问题,这是我的代码:
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
the problem was i had forgotten to file.close()I did it and fixed the problem.
问题是我忘记了file.close()我做了并解决了问题。
回答by Jeremy Li
The accepted answer is the easiest one to fix the problem. But in case you are not allowed to install the simplejson due to your company policy, I propose below solution to fix the particular issue of "using comma on the last item in a list":
接受的答案是最容易解决问题的答案。但是,如果由于您的公司政策而不允许您安装 simplejson,我建议使用以下解决方案来解决“在列表的最后一项上使用逗号”的特定问题:
Create a child class "JSONLintCheck" to inherite from class "JSONDecoder" and override the initmethod of the class "JSONDecoder" like below:
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)
创建一个子类“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)
- make_scanneris a new function that used to override the 'scan_once' method of the above class. And here is code for it:
- make_scanner是一个新函数,用于覆盖上述类的“scan_once”方法。这是它的代码:
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
- Better put the 'make_scanner' function together with the new child class into a same file.
- 最好将'make_scanner' 函数与新的子类放在同一个文件中。
回答by Jayhello
As to me, my json file is very large, when use common jsonin python it gets the above error.
对我来说,我的 json 文件非常大,json在 python 中使用 common时会出现上述错误。
After install simplejsonby sudo pip install simplejson.
安装后simplejson通过sudo pip install simplejson.
And then I solved it.
然后我解决了它。
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()
回答by Tomasz W
Just hit the same issue and in my case the problem was related to BOM(byte order mark) at the beginning of the file.
刚刚遇到同样的问题,在我的情况下,问题与BOM文件开头的(字节顺序标记)有关。
json.toolwould refuse to process even empty file (just curly braces) until i removed the UTF BOM mark.
json.tool甚至会拒绝处理空文件(只是花括号),直到我删除了 UTF BOM 标记。
What I have done is:
我所做的是:
- opened my json file with vim,
- removed byte order mark (
set nobomb) - save file
- 用vim打开我的json文件,
- 删除字节顺序标记 (
set nobomb) - 保存存档
This resolved the problem with json.tool. Hope this helps!
这解决了 json.tool 的问题。希望这可以帮助!

