当我在Python 3中使用json.loads并捕获任何结果错误时,例如:
try:
data = json.loads(string)
except ValueError as err:
print(err)
Run Code Online (Sandbox Code Playgroud)
我收到了一条有用的消息:
Expecting ',' delimiter: line 12 column 12 (char 271)
Run Code Online (Sandbox Code Playgroud)
我希望能够向用户显示这一点,以及导致问题的确切位置(我正在阅读用户编写的JSON).我该如何走出直线和列?
我可以在err上使用正则表达式,但这感觉是一个坏主意,因为我不知道这个消息是否国际化,并且可能在不同版本的python中发生变化.有没有更好的办法?
扫描json/decoder.py源代码,我们可以看到解码器的错误消息是使用以下errmsg函数构造的:
def errmsg(msg, doc, pos, end=None):
# Note that this function is called from _json
lineno, colno = linecol(doc, pos)
if end is None:
fmt = '{0}: line {1} column {2} (char {3})'
return fmt.format(msg, lineno, colno, pos)
#fmt = '%s: line %d column %d (char %d)'
#return fmt % (msg, lineno, colno, pos)
endlineno, endcolno = linecol(doc, end)
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
#fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
#return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
Run Code Online (Sandbox Code Playgroud)
由于这是一个纯python模块,因此可以使用自定义函数包装此函数.这个过程称为猴子修补:
import json
original_errmsg= json.decoder.errmsg
def our_errmsg(msg, doc, pos, end=None):
json.last_error_position= json.decoder.linecol(doc, pos)
return original_errmsg(msg, doc, pos, end)
json.decoder.errmsg= our_errmsg
try:
data = json.loads('{1:}')
except ValueError as e:
print("error at", json.last_error_position)
Run Code Online (Sandbox Code Playgroud)
显然,这个解决方案并不理想,因为实现可能会随时改变,尽管它仍然比依赖消息更好.您应该errmsg在修补之前检查是否存在(并且可能在没有其他参数或使用varargs时).
如果你使用simplejson库,你会得到一个合格的JSONDecodeError:
class JSONDecodeError(ValueError):
"""Subclass of ValueError with the following additional properties:
msg: The unformatted error message
doc: The JSON document being parsed
pos: The start index of doc where parsing failed
end: The end index of doc where parsing failed (may be None)
lineno: The line corresponding to pos
colno: The column corresponding to pos
endlineno: The line corresponding to end (may be None)
endcolno: The column corresponding to end (may be None)
"""
Run Code Online (Sandbox Code Playgroud)
希望这将很快合并到 stdlib 中。
在 Python 3.5 及更高版本中,将引发专门的JSONDecodeError而不是ValueError. 它有几个有用的属性 - 引用自文档:
msg:未格式化的错误消息。
doc:正在解析的 JSON 文档。:解析失败
pos的起始索引。: 对应的行。: 对应的列。doc
linenopos
colnopos
| 归档时间: |
|
| 查看次数: |
13997 次 |
| 最近记录: |