私はPythonでオープンソースプロジェクトのソースコードを持っています.プロジェクトにはモジュール(python)とモジュールを使用するGUIがあり、GUIはqtpythonで書かれています.GUIを使用し、その中でさまざまなアクションを実行しています.どのような関数が呼び出され、どこからログのようなものかを知り、ソース コードの UML ダイアグラムを生成して、それをよりよく理解し、プロジェクトに貢献できるようにする方法はありますか。プロジェクトが使用している Python のバージョンは 2.7 です。
2 に答える
コメントで述べたように、Python からの UML の生成については、この回答で既に説明されています。(Python は必ずしも UML で表現できる必要はないことに注意してください。ただし、表現可能であれば素晴らしいことです。)
実行時の制御の流れを確認するには、いくつかの方法があります。1 つは、プロファイリング ツールやデバッグ ツールを使用する方法です。しかし、それをログに記録する最も簡単な方法を見てみましょう。これはあなたが求めていたものです:
print
コンソールに ing するだけで、いつでも何でも「ログ」できます。GUI スタイルで起動するのではなく、コマンド ラインからアプリを実行する必要があります (Mac では、実行可能ファイル/スクリプトを直接実行する必要があり、.app
そこからビルドされたバンドルを実行する必要はありません)。ログ出力を取得しました。必要に応じて、シェル (Windows でもcmd
) を使用して、後で参照するためにこれをファイルにリダイレクトできます。これで十分でない場合はlogging
、標準ライブラリに組み込まれているモジュールを参照してください。
関数がどこから呼び出されているかを知りたい場合は、関数が呼び出されるたびにスタック トレースをログに記録できます。これは少し見にくいですが、必要なすべての情報を提供し、後で出力を解析するためのコードをいつでも記述できます。関数traceback.print_stackはまさにそれを行います。(さらに凝りたい場合は、他の関数を使用して情報を抽出し、必要に応じてフォーマットし、必要に応じてログに記録します。)
これを行うには、トレースするすべての関数に次の行を追加します。
traceback.print_stack()
これを行う別の方法は、monkey-patcher を作成し、関心のあるすべての関数に適用することです。
def tracify(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
traceback.print_stack()
func(*args, **kwargs)
return wrapper
次に、メイン スクリプトで次のようにします。
InterestingClass.interestingMethod = tracify(InterestingClass.interestingMethod)
これで、InterestingClass.interestingMethod が呼び出されるたびに、スタック トレースが出力されます。仕組みを理解する必要はありませんtracify
。関数に対して行うことを変更したい場合は、その行を変更したいものに置き換えてtraceback.print_stack()
ください。
では、クラス内のすべての「パブリック」メソッドにパッチを適用したい場合はどうすればよいでしょうか?
for attr in dir(InterestingClass):
if not attr.startswith('_'):
method = getattr(InterestingClass, attr)
if isinstance(method, instancemethod):
setattr(InterestingClass, tracify(method))
(これは Python 2 の場合です。Python 3 では状況が変わり、複雑なケースがはるかに単純になりますが、些細なケースはそれほど簡単ではありません。)
モジュール内のすべてのクラスのすべてのパブリック メソッドとすべてのフリー関数にパッチを適用したい場合はどうすればよいでしょうか? クラスの場合と同じように、モジュールを同じ方法で繰り返し処理し、それぞれの型を確認できます。
また、 inspectモジュールを使用して難しい作業を行うこともできます。しかし、Python を学んでいるだけなら、dir
コードをコピーして貼り付ける方が、使い方を学ぶよりもはるかに簡単だと思いますinspect
。言語に慣れたら、戻って遊んで、inspect
すべてが機能した理由を理解してください。
私はPythonを使用していませんが、プログラムの動作をリアルタイムで追跡する場合は、デバッガーを使用します。Pythonデバッガーを少しグーグルで検索すると、有望な結果が得られる場合があります。