ast.NodeTransformer

AI
qwen-3-235b-a22b-instruct-2507
작성자
익명
작성일
2026.02.03
조회수
1
버전
v1

ast.NodeTransformer

ast.NodeTransformer는 Python의 표준 라이브러리 ast(Abstract Syntax Tree, 추상 구문 트리) 모듈에 포함된 클래스로, 파이썬 코드를 파싱한 후 그 구조를 분석하고 수정하거나 변환하는 데 사용되는 강력한 도구입니다. 이 클래스는 코드 변환(code transformation), 정적 분석, 코드 생성, 코드 난독화, DSL(Domain-Specific Language) 구현 등 다양한 소프트웨어 개발 자동화 작업에 활용됩니다.


개요

파이썬 소스 코드는 문자열 형태로 존재하지만, ast 모듈을 사용하면 이를 구문 트리(Syntax Tree) 형태로 변환할 수 있습니다. 이 트리는 각 코드 요소(예: 변수, 함수, 조건문, 반복문 등)를 노드 객체로 표현하며, ast.NodeTransformer는 이러한 노드를 방문(visit)하고 필요 시 수정 또는 교체할 수 있게 해줍니다.

NodeTransformerast.NodeVisitor를 상속받아 기본적인 노드 탐색 기능을 제공하지만, 수정 기능을 추가로 지원합니다. 즉, 각 노드를 방문할 때 원본 노드를 그대로 반환할 수도 있고, 새로운 노드로 교체하거나 삭제할 수도 있습니다.


주요 기능과 동작 원리

1. 노드 변환의 기본 흐름

ast.NodeTransformer는 다음과 같은 방식으로 동작합니다:

  1. 파이썬 코드를 문자열로 입력받아 [ast.parse](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%ED%8C%8C%EC%9D%B4%EC%8D%AC%20%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/ast.parse)()로 구문 트리 생성.
  2. 생성된 트리를 순회하며 각 노드에 대해 visit_XXX 메서드 호출.
  3. 사용자가 정의한 visit_XXX 메서드에서 노드를 수정하거나 교체.
  4. 수정된 트리를 다시 파이썬 코드로 출력하거나, 다른 처리를 수행.

2. 주요 메서드: [generic_visit](/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EA%B0%9C%EB%B0%9C/%ED%8A%B8%EB%A6%AC%20%EC%88%9C%ED%9A%8C/generic_visit)()visit_XXX()

  • generic_visit(node): 기본적으로 모든 자식 노드를 재귀적으로 방문.
  • visit_FunctionDef(self, node): 함수 정의 노드를 방문할 때 호출.
  • visit_Call(self, node): 함수 호출 노드를 방문할 때 호출.
  • visit_BinOp(self, node): 이항 연산(예: +, *) 노드를 방문할 때 호출.

이러한 메서드를 오버라이드하여 원하는 방식으로 노드를 수정할 수 있습니다. 반환값이 None이면 해당 노드가 삭제되며, 새로운 노드를 반환하면 교체됩니다.


사용 예시

다음은 ast.NodeTransformer를 사용하여 특정 기능을 수행하는 예제입니다.

예제 1: 모든 덧셈을 곱셈으로 바꾸기

import ast

class AddToMultiply(ast.NodeTransformer):
    def visit_BinOp(self, node):
        if isinstance(node.op, ast.Add):
            node.op = ast.Mult()  # + 연산자를 *로 변경
        return self.generic_visit(node)

# 원본 코드
source_code = "result = 2 + 3 + 4"
tree = ast.parse(source_code)

# 변환 적용
transformer = AddToMultiply()
transformed_tree = transformer.visit(tree)

# 수정된 코드 출력
print(ast.unparse(transformed_tree))  # 출력: result = 2 * 3 * 4


예제 2: 함수 호출 로깅 자동 삽입

class LogFunctionCalls(ast.NodeTransformer):
    def visit_Call(self, node):
        # 함수 호출 주변에 print 추가
        log_call = ast.Expr(
            value=ast.Call(
                func=ast.Name(id='print', ctx=ast.Load()),
                args=[ast.Constant(value=f"Calling function: {node.func.id}")],
                keywords=[]
            )
        )
        # 원래 호출과 로그를 순차적으로 실행
        return [log_call, node]

# 원본 코드
source = "def greet(): pass\ngreet()"
tree = ast.parse(source)

# 트리 변환
transformer = LogFunctionCalls()
new_body = []
for node in tree.body:
    if isinstance(node, ast.Expr) and isinstance(node.value, ast.Call):
        new_body.extend(transformer.visit(node))
    else:
        new_body.append(node)

tree.body = new_body
print(ast.unparse(tree))

출력 예시:

> def greet():
>     pass
> print('Calling function: greet')
> greet()
> 


주의사항 및 한계

  • 문법 오류 주의: 잘못된 노드 구조를 생성하면 [ast.unparse](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%ED%8C%8C%EC%9D%B4%EC%8D%AC%20%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/ast.unparse)() 또는 compile() 시 오류 발생.
  • 문맥 유지: ctx 필드(예: Load, Store, Del)를 올바르게 설정해야 함.
  • 성능: 대규모 코드 기반에 적용 시 성능 저하 가능성 있음.
  • 동적 코드 비대응: eval()이나 exec()로 실행되는 동적 코드는 분석 불가.

활용 분야

분야 설명
정적 분석 도구 코드 스타일 검사, 버그 탐지 (예: pylint, flake8)
코드 난독화 변수 이름 변경, 로직 변형 등 보안 강화
DSL 구현 도메인 특화 언어를 파이썬 문법 위에 구현
자동 리팩터링 IDE의 리팩터링 기능 (예: 변수 이름 일괄 변경)
테스트 자동화 함수 호출 로깅, 실행 경로 추적 등

참고 자료


ast.NodeTransformer는 파이썬의 동적 특성과 메타프로그래밍 능력을 극대화할 수 있는 핵심 도구입니다. 코드를 데이터처럼 다룰 수 있는 능력은 고급 자동화와 도메인 특화 언어 개발에 있어 매우 중요한 자산이 됩니다.

AI 생성 콘텐츠 안내

이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?