通过字符串列表访问json数据?

2024-04-25 07:00:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个json:

json = {
    "state": {
        "reported": {
            "figure": {"x":10, "y":12, "z":12},
            "gif": {"x":10,"y":12, "z":12}
        }
    }
}

以及以下字符串列表:

lista = ["json['state']['reported']['figure']['x']",
         "json['state']['reported']['figure']['y']",
         "json['state']['reported']['gif']['z']"]

我想知道是否有一种方法可以使用这个列表获得json的结果?你知道吗


Tags: 方法字符串json列表giffigurestatelista
2条回答

正如在另一个答案中指出的,您可以使用eval来实现这一点。甚至还有一些技巧让黑客更难控制你的系统。到目前为止,这是最简单的路线,但是,没有一个明确的方法来确保这一点。你玩的那些把戏只会给你一种虚假的安全感。因此,如果您不完全信任lista的来源,就不要使用它。坏事总会发生的。你知道吗

好消息是,如果您愿意编写(或复制/粘贴)更多的代码,我们可以使用python的AST来安全地完成这项工作。诀窍是将字符串解析为AST。然后,我们将创建一个类,该类可以遍历AST并在找到特定类型的节点时采取适当的(安全的)操作。在您的示例中,我们需要处理4种类型的节点:

  • Str:表示字符串文本。你知道吗
  • Name:表示名称查找。e、 g.json
  • Subscript:表示__getitem__调用。你知道吗
  • Index:将传递给__getitem__的对象。一般来说,这也可以是一个切片,但是您所显示的输入中没有这个切片,所以我们现在不支持它。你知道吗

您可能需要的其他类型的节点(取决于输入)有NumSlice。一旦你摸索了ast reference(如果你以前没有看过它的话,这可能会有点模糊),就应该直接实现它们。你知道吗

现在写我们的课看起来很简单:

class Evaluator(ast.NodeVisitor):
    def __init__(self, globals):
        self._globals = globals

    def visit_Str(self, n):
        return n.s

    def visit_Name(self, n):
        return self._globals[n.id]

    def visit_Subscript(self, n):
        item = self.visit(n.value)
        slce = self.visit(n.slice)
        return item[slce]

    def visit_Index(self, n):
        return self.visit(n.value)

    def visit_Expr(self, n):
        return self.visit(n.value)

实际上,它看起来像:

e = Evaluator({'json': json})
print([e.visit(ast.parse(s).body[0]) for s in lista])

可以使用python的eval函数。也就是说,这是一个非常糟糕的想法,因为eval是一个危险的函数。有关eval函数的更多信息,请查看此链接:https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

json = {
    "state": {
        "reported": {
            "figure": {"x": 10, "y": 12, "z": 12},
            "gif": {"x": 10, "y": 12, "z": 12}
        }}}

lista = [
    "json['state']['reported']['figure']['x']",
    "json['state']['reported']['figure']['y']",
    "json['state']['reported']['gif']['z']"
]

values = [eval(x) for x in lista]

相关问题 更多 >