2016-04-14 2 views
1

Использование ast и astor библиотеки, я написал простой скрипт, который проходит в AST с помощью ast.NodeTransformer и заменяет все пустые списки с None:Как я могу прервать посетителя AST и оставить исходный узел без изменений?

import ast 
import astor 


class ListChanger(ast.NodeTransformer): 
    def visit_List(self, node): 
     if len(node.elts) > 0: 
      return ast.copy_location(node, node) 
     return ast.copy_location(ast.NameConstant(value=None), node) 

x = ast.parse("""["A"]""") 
ListChanger().visit(x) 
print(astor.to_source(x)) 

y = ast.parse("""[]""") 
ListChanger().visit(y) 
print(astor.to_source(y)) 

Это работает правильно, и выходы:

["A"] 
None 

Однако я не уверен в том, что я использовал, чтобы выйти из функции, если список пуст:

return ast.copy_location(node, none) 

Если я заменил это на return, сделав сценарий возвратом None, если это условие не выполнено, узел уничтожается, а не остается неизменным, в результате чего первый тестовый пример печатает пустую строку, потому что узел ast.List уничтожен.

Я не хочу, чтобы это произошло, но я также думаю, что использование ast.copy_location(node, node) кажется неправильным. Есть ли специальная функция, чтобы оставить узел неизменным и выйти из функции, или способ настроить ast.NodeTransformer, чтобы, если функция visit возвращает None, узел остается неизменным?

ответ

1

Из documentation:

Возвращаемое значение может быть оригинальный узел в этом случае замена не происходит.

Таким образом, вместо:

return ast.copy_location(node, none) 

просто:

return node 
+0

Brilliant - не думаю, чтобы посмотреть в документации. Спасибо! –