저는 AST 조작으로 놀고 있습니다. 현재 입력 AST에서 특정 노드를 제거하려고합니다. NodeTransformer 클래스는이 목적을위한 적절한 툴이라고 생각합니다. 슬프게도 예상대로 동작하지 않습니다.Python NodeTransformer : 노드를 제거하는 방법?
documetation는 말한다 :
는 "NodeTransformer는 AST를 걸어 교체하거나 이전 노드를 제거하는 방문자 방법의 반환 값을 사용하는 방문자 메소드의 반환 값이 없음이없는 경우, 노드는 것이다. 해당 위치에서 제거해야합니다. 그렇지 않으면 반환 값으로 바뀝니다. "
지금 내 프로그램을보고 :
l = [0, 1, 2, 3]
total = 0
for i in l:
total += i
print(total)
그리고 결과 : 여기
import _ast
import ast
import sys
#ast transformer
class MyTransformer(ast.NodeTransformer):
def iterate_children(self, node):
"""
helper
"""
children = ast.iter_child_nodes(node)
for c in children:
self.visit(c)
def generic_visit(self, node):
"""
default behaviour
"""
print("visiting: "+node.__class__.__name__)
self.iterate_children(node)
return node
def visit_For(self, node):
"""
For nodes: replace with nothing
"""
print("removing a For node")
return None
#read source program
filename = sys.argv[1]
with open (filename, "r") as myfile:
source = str(myfile.read())
#compile source to ast
m = compile(source, "<string>", "exec", _ast.PyCF_ONLY_AST)
#do ast manipulation
t = MyTransformer()
t.visit(m)
# fix locations
m = ast.fix_missing_locations(m)
#visualize the resulting ast
#p = AstPrinter()
#p.fromAst(m)
#execute the transformed program
print("computing...")
codeobj = compile(m, '<string>', 'exec')
exec(codeobj)
입력 파일입니다
visiting: Module
visiting: Assign
visiting: Name
visiting: Store
visiting: List
visiting: Num
visiting: Num
visiting: Num
visiting: Num
visiting: Load
visiting: Assign
visiting: Name
visiting: Store
visiting: Num
removing a For node
visiting: Expr
visiting: Call
visiting: Name
visiting: Load
visiting: Name
visiting: Load
computing...
6
내가 '0'기대의 때문에 루프가 제거되었습니다. 그러나 '6'(= 0 + 1 + 2 + 3)이 있습니다.
이유를 아는 사람이 있습니까?
파이썬 버전 : 3.2.3
숫자는() 입력 프로그램의 줄 번호를 나타냅니다. 이미지 그리기 코드는 여기에 제공되지 않습니다. "루트"노드를 무시하십시오. 보시다시피 For 루프가 아직 있습니다.
읽어 주셔서 감사합니다.
업데이트 21.8 :
나는 파이썬 메일 링리스트 ([email protected])에이 질문에 대한 링크를 게시했다. 너무 많이 겹쳐 쓴 것처럼 보입니다. 어린이 방문객이 없으면 예상대로 작동합니다. MyTransformer의
전체 소스 코드 : 당신이 자기 기록 generic_visit()
을 제거하기 때문에
class MyTransformer(ast.NodeTransformer):
def visit_For(self, node):
"""
For nodes: replace with nothing
"""
print("removing a For node")
return None