2017-03-21 3 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上のPython 3.5を実行しているときに、問題が明らかではありません。しかし、トレースログが出力されないように、Python 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)) 

出力Iは、以下を参照してください。

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

質問のコードは、情報を表示する際にもう少し堅牢で役立つように拡張されました。 WindowsでPython 3.5とPython 3.6の出力が異なるかどうか確認できますか? –

関連する問題