Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:JSON解码库,可以将解码项与原始行号关联?_Python_Json - Fatal编程技术网

Python:JSON解码库,可以将解码项与原始行号关联?

Python:JSON解码库,可以将解码项与原始行号关联?,python,json,Python,Json,我经常对用户可编辑的配置文件使用JSON。格式错误的JSON当然是由JSON.loads为我挑选的,但有时会出现错误,直到我检查结果dicts/list/strings时才发现。我希望能够给出一些有用的错误,比如“第23行的无效值‘foo’”,但当我拿回dict时,我丢失了与原始行号的任何映射 可能有人编写了一个JSON解析器,用一些元数据标记每个输出对象在输入文本中的位置:python是否存在这样的东西 示例: 1. [{"foo": "x"}, 2. {"bar": "y"}] 解析上述

我经常对用户可编辑的配置文件使用JSON。格式错误的JSON当然是由
JSON.loads
为我挑选的,但有时会出现错误,直到我检查结果dicts/list/strings时才发现。我希望能够给出一些有用的错误,比如“第23行的无效值‘foo’”,但当我拿回dict时,我丢失了与原始行号的任何映射

可能有人编写了一个JSON解析器,用一些元数据标记每个输出对象在输入文本中的位置:python是否存在这样的东西

示例:

1. [{"foo": "x"},
2.  {"bar": "y"}]

解析上述内容后,我发现“y”实际上不是“bar”的合法值,我想知道它来自第2行。

如果使用
json.load()
并传入一个打开的文件句柄,则得到的任何错误消息都会有一个行和列号。如果异常是
ValueError
,则关联的消息应该适合转发给用户。

如果您想要的东西不存在,但我有一个主意,如果您感兴趣,可以如何实现它

json模块有一个用于解码对象的钩子,您可以(错误地)使用它来执行解码时间对象验证。但是,这并不能解决您的问题,因为钩子没有获取行号信息。这个问题变得更加复杂,因为在Python2.7+中不再会收到逐行错误消息。您只能从纯Python JSON解码器获得它们,而较新版本使用(快得多)的C库

所以我们有两个问题要解决

1) 您可以通过子类化json.JSONDecoder使用纯python解码器,如下所示:

class PyDecoder(json.JSONDecoder):
    def __init__(self, encoding=None, object_hook=None, parse_float=None,
            parse_int=None, parse_constant=None, strict=True,
            object_pairs_hook=None):
        super(PyDecoder, self).__init__(encoding, object_hook, parse_float,
                                        parse_int, parse_constant, strict)
        self.scan_once = json.scanner.py_make_scanner(self)

2) 要获得验证,您需要用一个方法替换json.decoder.JSONObject,该方法的作用几乎相同,但也会将行号信息传递给验证例程。

完全公开:我是下面包的维护者

现在有一个新的Python包解决了这个用例:

安装:
pip安装json\u源代码\u映射

例如,在您的情况下:

from json_source_map import calculate

source = '''[{"foo": "x"},
{"bar": "y"}]'''

print(calculate(source))
这张照片是:

{
    "": Entry(
        value_start=Location(line=0, column=0, position=0),
        value_end=Location(line=1, column=13, position=28),
        key_start=None,
        key_end=None,
    ),
    "/0": Entry(
        value_start=Location(line=0, column=1, position=1),
        value_end=Location(line=0, column=13, position=13),
        key_start=None,
        key_end=None,
    ),
    "/0/foo": Entry(
        value_start=Location(line=0, column=9, position=9),
        value_end=Location(line=0, column=12, position=12),
        key_start=Location(line=0, column=2, position=2),
        key_end=Location(line=0, column=7, position=7),
    ),
    "/1": Entry(
        value_start=Location(line=1, column=0, position=15),
        value_end=Location(line=1, column=12, position=27),
        key_start=None,
        key_end=None,
    ),
    "/1/bar": Entry(
        value_start=Location(line=1, column=8, position=23),
        value_end=Location(line=1, column=11, position=26),
        key_start=Location(line=1, column=1, position=16),
        key_end=Location(line=1, column=6, position=21),
    ),
}

这将准确地告诉您每个键和值在原始JSON文档中的起始和结束位置。例如,它告诉您
“y”
位于第1行(行的索引为零),从第8列开始,到第11列结束。

当然,我已经收到了关于JSON级别语法错误的好消息。这个问题是关于如何处理错误的,我在查看结果对象之前没有发现这些错误。对不起,我误解了这个问题。不幸的是,我认为Python没有这样的库,或者至少我在主要的JSON库(JSON、simplejson、Jansson)中没有看到这一特性