2017-11-19 14 views
0

나는 Python 프로그램 (내부 코드 삽입)을 도구로 사용하는 방법을 찾고있다. 예를 들어, 프로그램이 if 조건 인 x > 2에 도달하면 콘솔 x > 2에 인쇄하는 if 조건에 따라 print 문을 자동으로 추가하려고합니다.if 문 내부의 조건을 인쇄 할 수 있도록 파이썬 프로그램에 코드를 삽입하는 방법은 무엇입니까?

프로그램의 소스 코드를 사용할 수 없습니다.

+0

코드에서'logging' 모듈을 사용하거나 디버거를 사용하여 * 명시 적으로 * 사용하지 않습니까? – chepner

+0

@chepner yeah without the those. 나는 그들이 실행될 때 ** if ** 문을 기록하고 (** 실행되지 않으면 ** else **) 그들의 조건을 출력하려고합니다. 디버거를 찾고 있지 않습니다. –

+1

if 후에 print 문을 추가하지 않는 이유는 무엇입니까? – user1767754

답변

1

ast 모듈을 사용할 수 있지만 여전히 소스가 필요합니다. 바이트 코드 만있는 경우에는 소스를 다시 얻으려면 uncompyle6과 같은 것을 사용해야합니다. 자동으로이 작업을 수행하므로 소스가 난독 화되는지는 중요하지 않습니다. 당신이 간부 foo는, 당신이 얻을 경우

def foo(x): 
    if x > 100: 
     print('big') 
    else: 
     print('small') 


if __name__ == '__main__': 
    foo(5) 
    foo(500) 

: 시험 인 경우

small 
big 

는 이제 모든 if 문의 시험 절을 인쇄 할

은이 같은 모듈이 있다고 가정 True.

>>> tree = ast.parse(source) 

다음 단계는 다음과 같습니다

>>> source = inspect.getsource(foo) 

는 추상 구문 트리를 얻기 위해 소스를 분석 할 수 있습니다 :

>>> import foo 

그런 다음 소스 코드를 얻을 : foo는 가져 시작할 수 있습니다 트리를 수정할 NodeTransformer 정의 :

>>> class IfTransformer(ast.NodeTransformer): 
     def visit_If(self, node): 
      new_node = ast.Expr(value=ast.Call(
        func=ast.Name(id='print', ctx=ast.Load()), 
        args=[ast.Str(s=astunparse.unparse(node.test))], 
        keywords=[] 
      )) 
      node.body.insert(0, new_node) 
      return ast.fix_missing_locations(node) 
시험이 True 인 경우 각 if 절 들어

>>> exec(compile(tree, 'foo.py', 'exec')) 
(__name__ == '__main__') 

small 
(x > 100) 

big 

:

>>> IfTransformer().visit(tree) 

그런 다음 컴파일하고 새로운 소스를 실행할 수 있습니다 : 트리를 수정하기 위해 6,

우리는 우리의 IfTransformer 방문하는 모든 노드를 만들 테스트 결과가 나왔습니다. 너 같은 현명한 사람이 여기에서 모든 것을 알아낼 수있다.

체크 아웃 this video from Pycon 2011