ここで、関数コードに散在する出力関数をデバッグするためのコストのかかる呼び出しをすべて削除する方法について私が尋ねた他の質問に対する解決策を思いつきました (空の function を使用すると速度が 25 倍になりましたlambda *p: None
)。
解決策は、関数コードを動的に編集し、すべての関数呼び出しの前にコメント記号を追加すること#
です。
from __future__ import print_function
DEBUG = False
def dprint(*args,**kwargs):
'''Debug print'''
print(*args,**kwargs)
def debug(on=False,string='dprint'):
'''Decorator to comment all the lines of the function code starting with string'''
def helper(f):
if not on:
import inspect
source = inspect.getsource(f)
source = source.replace(string, '#'+string) #Beware! Swithces off the whole line after dprint statement
with open('temp_f.py','w') as file:
file.write(source)
from temp_f import f as f_new
return f_new
else:
return f #return f intact
return helper
def f():
dprint('f() started')
print('Important output')
dprint('f() ended')
f = debug(DEBUG,'dprint')(f) #If decorator @debug(True) is used above f(), inspect.getsource somehow includes @debug(True) inside the code.
f()
私が今見ている問題は次のとおりです。
#
すべての行を最後までコメントします。で区切られた他のステートメントが存在する場合があります;
。pprint
これは、コメントではなく内のすべての呼び出しを削除することで対処できますがf
、ネストされた括弧がある可能性があるため、それほど簡単ではないかもしれません。temp_f.py
が作成され、そこから新しいf
コードがロードされます。ハードドライブに書き込まずにこれを行うためのより良い方法があるはずです。私はこのレシピを見つけましたが、それを機能させることができませんでした.- 特殊な構文 used
@debug
を使用してデコレータが適用されている場合inspect.getsource
は、関数コードにデコレータのある行が含まれます。この行は文字列から手動で削除できますが、複数のデコレータが に適用されている場合、バグが発生する可能性がありますf
。古いスタイルのデコレータアプリケーションに頼って解決しましたf=decorator(f)
。
ここで他にどのような問題が見られますか?
これらの問題をすべて解決するにはどうすればよいでしょうか。
このアプローチの長所と短所は何ですか?
ここで何を改善できますか?
このコードで達成しようとしていることを行うためのより良い方法はありますか?
関数コードをバイトコードにコンパイルする前に前処理することは、非常に興味深く論争の的となる手法だと思います。誰もそれに興味を持っていないのは奇妙ですが。私が与えたコードには、多くの不安定な点があると思います。