首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在literal_eval之前,如何在Python AST中用dict替换OrderedDict?

在literal_eval之前,如何在Python AST中用dict替换OrderedDict?
EN

Stack Overflow用户
提问于 2018-07-10 03:51:32
回答 2查看 779关注 0票数 6

我有一个包含Python代码的字符串,如果只将OrderedDict的实例替换为{},我可以用literal_eval将其计算为Python。

我尝试使用ast.parseast.NodeTransformer来进行替换,但是当我使用nodetype == 'Name' and node.id == 'OrderedDict'捕获节点时,我找不到作为节点对象中的参数的列表,因此我可以用Dict节点替换它。

这是正确的方法吗?

下面是一些代码:

代码语言:javascript
复制
from ast import NodeTransformer, parse

py_str = "[OrderedDict([('a', 1)])]"

class Transformer(NodeTransformer):
    def generic_visit(self, node):
        nodetype = type(node).__name__

        if nodetype == 'Name' and node.id == 'OrderedDict':
            pass # ???

        return NodeTransformer.generic_visit(self, node)

t = Transformer()

tree = parse(py_str)

t.visit(tree)
EN

回答 2

Stack Overflow用户

发布于 2018-07-10 06:09:58

您可以使用ast.NodeVisitor类观察OrderedDict树,以便使用从空字典解析的节点作为基础,从遇到的节点手动构建{}树。

代码语言:javascript
复制
import ast
from collections import deque


class Builder(ast.NodeVisitor):
    def __init__(self):
        super().__init__()
        self._tree = ast.parse('[{}]')
        self._list_node = self._tree.body[0].value
        self._dict_node = self._list_node.elts[0]
        self._new_item = False

    def visit_Tuple(self, node):
        self._new_item = True
        self.generic_visit(node)

    def visit_Str(self, node):
        if self._new_item:
            self._dict_node.keys.append(node)
        self.generic_visit(node)

    def visit_Num(self, node):
        if self._new_item:
            self._dict_node.values.append(node)
            self._new_item = False
        self.generic_visit(node)

    def literal_eval(self):
        return ast.literal_eval(self._list_node)


builder = Builder()
builder.visit(ast.parse("[OrderedDict([('a', 1)])]"))
print(builder.literal_eval())

注意,这只适用于使用str作为键和int作为值的示例的简单结构。但是,应该可以以类似的方式扩展到更复杂的结构。

票数 0
EN

Stack Overflow用户

发布于 2018-07-10 17:38:18

除了使用ast解析和转换表达式之外,您还可以使用正则表达式进行解析和转换。例如:

代码语言:javascript
复制
>>> re.sub(
...     r"OrderedDict\(\[((\(('[a-z]+'), (\d+)\)),?\s*)+\]\)",
...     r'{\3: \4}',
...     "[OrderedDict([('a', 1)])]"
... )
"[{'a': 1}]"

上面的表达式基于OP的示例字符串,并将单引号字符串作为键,正整数作为值,当然,它可以扩展到更复杂的情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51253056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档