无返回时处理 JSON 解码错误
Posted
技术标签:
【中文标题】无返回时处理 JSON 解码错误【英文标题】:Handle JSON Decode Error when nothing returned 【发布时间】:2012-01-12 22:48:12 【问题描述】:我正在解析 json 数据。我没有解析问题,我正在使用simplejson
模块。但是一些 api 请求返回空值。这是我的例子:
"all" :
"count" : 0,
"questions" : [ ]
这是我解析 json 对象的代码段:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
正如我提到的一些请求,我收到以下错误:
Traceback (most recent call last):
File "YahooQueryData.py", line 164, in <module>
qUserData = json.loads(qByUser)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/__init__.py", line 385, in loads
return _default_decoder.decode(s)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/decoder.py", line 402, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/decoder.py", line 420, in raw_decode
raise JSONDecodeError("No JSON object could be decoded", s, idx)
simplejson.decoder.JSONDecodeError: No JSON object could be decoded: line 1 column 0 (char 0)
处理此错误的最佳方法是什么?
【问题讨论】:
其实,你的问题是什么? 你回答了问题;)看起来我在真正输入问题之前提交了问题。感谢您的回答。 好的,我很高兴能帮上忙——现在看起来像是心灵感应;)不过,感谢您提出问题。祝你好运! 【参考方案1】:Python 编程中有一条规则叫做“请求宽恕比请求许可更容易”(简称:EAFP)。这意味着您应该捕获异常而不是检查值的有效性。
因此,请尝试以下操作:
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except ValueError: # includes simplejson.decoder.JSONDecodeError
print('Decoding JSON has failed')
编辑:由于simplejson.decoder.JSONDecodeError
实际上继承自ValueError
(proof here),我只使用ValueError
简化了catch 语句。
【讨论】:
您应该始终捕获正确的异常。否则,如果存在实际的ValueError
异常或其他一些也继承自 ValueError
的异常,您可能会遗漏代码中的错误。
@JulieinAustin:问题是在这种情况下你真的没有太多选择——stdlib 的 json 模块会抛出 ValueError。
那么我会远离那个解码器。最初的问题是关于simplejson
模块,它确实会在输入错误时引发JSONDecodeError
。查看您之前的链接。
@JulieinAustin:我会这样做,因为它实际上是......标准库。如果您不关心速度太多,我会使用现有的。是的,simplejson
以更细粒度的方式执行此操作,但它有其自身的问题。如果try...except
块只封装json.loads
调用,你会怎么说?我认为这样会更好,但需要一些锅炉位置来满足要求(例如,将异常的类更改为更细粒度的东西,但不要试图在这里拯救世界)。
ValueError
过于宽泛,无法在此上下文中使用。我相信在用户代码方面qUserData["all"]["questions"]
也可以抛出ValueError
。更不用说ValueError
在simplejson
内的其他地方提出了。当事情“无缘无故”开始破裂时,这种事情可能会在 6 个月后让你非常痛苦【参考方案2】:
如果您不介意导入json
模块,那么处理它的最佳方法是通过json.JSONDecodeError
(或json.decoder.JSONDecodeError
,因为它们是相同的),因为使用ValueError
之类的默认错误也可以捕获其他的异常不一定和json解码有关。
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
//编辑(2020 年 10 月):
正如@Jacob Lee 在评论中指出的那样,当 JSON 对象不是 str
、bytes
或 bytearray
时,可能会引发基本的公共 TypeError
。你的问题是关于JSONDecodeError
,但在这里还是值得一提的;为了处理这种情况,但要区分不同的问题,可以使用以下方法:
from json.decoder import JSONDecodeError
try:
qByUser = byUsrUrlObj.read()
qUserData = json.loads(qByUser).decode('utf-8')
questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
# do whatever you want
except TypeError as e:
# do whatever you want in this case
【讨论】:
不幸的是,当 JSON 对象不是 str、bytes 或 bytearray 时,json.loads 会引发 TypeError。这让我最近有点吃惊,因为我认为 JSONDecodeError 处理了这些情况,例如当 json.loads 的参数最终为 None 时。 @JacobLee:谢谢。最初的问题是关于处理JSONDecodeError
的最佳方法,所以我只关注那个,但你是对的,这个案例绝对值得一提。我已将其添加到答案中。以上是关于无返回时处理 JSON 解码错误的主要内容,如果未能解决你的问题,请参考以下文章
使用无控制台和无调试选项时,可执行文件上的 Pyinstaller 编解码器错误