扫描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)
由于这是一个纯 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)
显然,这种解决方案并不理想,因为实现可能随时发生变化,尽管它仍然比依赖消息要好。您应该在修补之前检查是否errmsg
存在(并且可能如果没有其他参数,或者使用可变参数)。