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

Python 通过字符串列表访问json数据?,python,arrays,json,python-2.7,dictionary,Python,Arrays,Json,Python 2.7,Dictionary,我有一个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['stat

我有一个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的结果?

您可以使用python的eval函数。这就是说,这是一个非常糟糕的想法,因为eval是一个危险的函数。有关评估功能的更多信息,请查看此链接:


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

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

Str:表示字符串文字。 名称:表示名称查找。e、 g.json 下标:表示一个uuu getitem_uuuuu调用。 索引:将被传递给_ugetItem__;的对象。一般来说,这也可能是一个切片,但您显示的输入中没有这个切片,因此我们现在不支持它。 根据输入可能需要的其他类型的节点有Num和Slice。一旦你摸索了这个问题,就应该直接实现它们。如果你以前没有看过这个问题,这个问题可能会有点模糊

现在,编写我们的类开始变得非常简单:

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])

您可以使用regex提取列表中的dict键,然后递归地从json对象获取值。但理想情况下,您应该更改逻辑以在列表中形成该字符串,而不是创建键列表,如果可能的话,可以使用一种不安全但有效的方法:result=[evalitem for item in lista]。对于硬编码数据并不是那么不安全。请不要将eval用于此项或任何相关内容。有像jsonpath这样的模块是为此而设计的。@zwer我不明白为什么每个人都反对eval。当然,evalinput请求代码inj,但是这个x=eval'1'有什么问题吗?如果我有例如:json1=json.dumpsjson?????你能告诉我如何使用这个sscript吗?阿德勒:你接下来的问题毫无意义,因为你试图用json来表示问题中的json模块和字典变量。您可以使用import json作为json_模块来避免这种情况,这将允许您编写json1=json_module.dumpsjson,e=Evaluator{'json':json},然后为lista中的s打印[e.visitast.parses.body[0]。
e = Evaluator({'json': json})
print([e.visit(ast.parse(s).body[0]) for s in lista])