Библиотека Python AST для получения всех операторов присваивания - PullRequest
0 голосов
/ 31 января 2019

Я смотрю в библиотеку Python ast, чтобы пройти AST и получить все назначения.Как я могу пройти по дереву, чтобы получить только операторы присваивания в python, используя библиотеку ast?

1 Ответ

0 голосов
/ 15 мая 2019

Вы можете использовать методы ast.NodeTransformer и visit_Assign и visit_AugAssign.Вот краткая демонстрация:

import ast
import inspect

def f():
    a = 1
    # Something else
    print("test")
    a += 1

class CustomNodeTransformer(ast.NodeTransformer):
    def visit_Assign(self, node):
        print("\nvisit_Assign")
        print(node.__dict__)
        print(node.targets[0].__dict__)
        print(node.value.__dict__)
        return node
    def visit_AugAssign(self, node):
        print("\nvisit_AugAssign")
        print(node.__dict__)
        print(node.target.__dict__)
        print(node.value.__dict__)
        return node

nodes = ast.parse(inspect.getsource(f))
CustomNodeTransformer().visit(nodes)

Что печатает:

visit_Assign
{'targets': [<_ast.Name object at 0x7fdca78a10b8>], 'value': <_ast.Num object at 0x7fdca78a1080>, 'lineno': 2, 'col_offset': 4}
{'id': 'a', 'ctx': <_ast.Store object at 0x7fdca78b0198>, 'lineno': 2, 'col_offset': 4}
{'n': 1, 'lineno': 2, 'col_offset': 8}

visit_AugAssign
{'target': <_ast.Name object at 0x7fdca7585048>, 'op': <_ast.Add object at 0x7fdca78b0f60>, 'value': <_ast.Num object at 0x7fdca7585080>, 'lineno': 5, 'col_offset': 4}
{'id': 'a', 'ctx': <_ast.Store object at 0x7fdca78b0198>, 'lineno': 5, 'col_offset': 4}
{'n': 1, 'lineno': 5, 'col_offset': 9}

Относительно примера:

  • Узлы дерева AST взяты из источникакод функции f в качестве примера.Вы можете использовать любое дерево, которое вам нравится.
  • visit_Assign имеет список targets в случае присвоений, например a = b = 1.В примере просто используется targets[0].
  • NodeTransformer, предназначенный для изменения узлов.Так что без return в описанных выше методах это будет похоже на return None, который удалит узлы из дерева.
  • Если ни один из вашего кода не должен изменять что-либо из узлов, то в этом нет необходимостив любом случае использовать ast.NodeTransformer, и вместо этого вы можете использовать ast.NodeVisitor.Тогда вам не нужно return.
...