2017-03-21 5 views
2

다른 질문에 답하려고 할 때 이론적으로 제어 할 수 없을 때 언제든지 스레드에서 코드를 실행할 수 있다는 것이 나에게 떠올랐다. CPython은 하나의 코드에 추적 함수를 등록하기위한 settrace 함수를 가지고 있습니다. 이 아이디어를 클래스의 사용으로부터 테스트하기 위해 다음 코드가 작성되었습니다. 문제는 추적이 발생하지 않으며 추적 로그에 데이터가 생성되지 않는다는 것입니다. 아래 코드에서 문제의 원인은 무엇입니까? "sys.settrace"는 Python 3.5에서는 제대로 작동하지만 Python 3.6에서는 제대로 작동하지 않습니까?

#! /usr/bin/env python3 
import atexit 
import collections 
import pprint 
import sys 


def main(): 
    i = create_instance() 
    print(len(i.data), flush=True) 


def create_instance(): 
    instance = Tracer() 
    return instance 


class Tracer: 

    def __init__(self): 
     self.data = [] 
     sys.settrace(self.trace) 
     atexit.register(pprint.pprint, self.data) 
     atexit.register(sys.settrace, None) 

    def trace(self, frame, event, arg): 
     print('Tracing ...', flush=True) 
     self.data.append(TraceRecord(frame, event, arg)) 
     return self.trace 


TraceRecord = collections.namedtuple('TraceRecord', 'frame, event, arg') 


if __name__ == '__main__': 
    main() 


부록 : Windows에서 파이썬 3.5를 실행하는 경우

문제는 분명하지 않다. 그러나 추적 로그가 인쇄되지 않도록 파이썬 3.6에서는 추적이 발생하지 않습니다. 누군가가 나를 위해 버그를 잘 제시된 대답으로 확인할 수 있다면 제출물이 수락되어 현상금을 수여받을 수있는 좋은 기회가됩니다.

+0

귀하의 코드와 함께 잘 작동 나 (CPython 3.6.1) ... 그러나'len' /'print'는 다루지 않으므로'main' 내의 아무 것도 추적되지 않습니다. 'main'의 중간에 수동으로 정의 된 함수를 호출 해보십시오. – Zulan

답변

1

나는 당신의 프로그램을 시험해 보았고 실제로 게시 된 것으로 추적 할 것이 없다. 내장 함수 print()len()은 추적 이벤트를 생성하지 않습니다. 아마도 플랫폼에 의해 정의되고 내부가 올바르게 작동하고 흥미롭지 않다고 가정하기 때문입니다.

문서 상태 :

추적 기능은 새로운 로컬 범위가 입력 될 때마다 ('호출'로 설정 이벤트와 함께) 호출;

프로그램을 수정하여 함수를 정의하고 호출했습니다. 이 작업을 수행하면 추적 기능이 호출되었습니다.

기능은 내가 정의 :

def doSomething(): 
    print("Hello World") 

당신의 main() 기능의 나의 버전 :

def main(): 
    i = create_instance() 
    print(len(i.data)) 
    doSomething() 
    print(len(i.data)) 

출력 내가 참조 :

0 
Tracing ... 
Tracing ... 
Hello World 
Tracing ... 
3 
+0

질문에 대한 코드가 정보를 표시 할 때 좀 더 강력하고 도움이되도록 확장되었습니다. Windows에서 파이썬 3.5와 파이썬 3.6의 출력이 다른지 확인할 수 있습니까? –