どのDebug
モジュールからインポートされているかをどのように知ることができますか? 答え: できません。Debug
複数のモジュールにインポートされている場合、複数回実行することをどのように知ることができますか? 回答: そうはなりません。モジュールは 1 回だけ実行され、その後キャッシュされます。だから、あなたがやりたいことは、あなたが望むほど簡単にはできません。
debug
ただし、インポート後にモジュール内の関数を呼び出すことでそれを行うことができます。__name__
呼び出し元のモジュールから渡してその名前を指定できます。その後、モジュール自体への参照を取得し、その中で定義されているトップレベルの変数を取得できます。その一部は関数である可能性があります。これらを装飾することができます。
# debug.py
import types, sys, functools
# decorator to be applied to all top-level functions in a module
def debug(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
print "calling", fn.__name__, "with args", *args, **kwargs
result = fn(*args, **kwargs)
print "returning from", fn.__name__, "with return value", result
return result
# decorate all top-level functions in named module with a given decorator
# (by default it is the above decorator but it could be a different one)
# This makes these functions behave as though they had been written with
# @debug above them.
def set_debug(modname, debug=debug):
module = sys.modules[modname]
for name in dir(module):
if not name.startswith("_"):
thing = getattr(module, name)
if isinstance(thing, types.FunctionType):
setattr(module, name, debug(thing))
呼び出しモジュールで:
# main.py
import debug
def main():
print "in main module"
debug.set_debug(__name__) # install debugging decorator
main()
(モジュール名ではなく) 名前空間を明示的に渡すという Jim Garrison のアプローチも優れており、実際には少し単純化されています。モジュール以外のものを装飾するために使用できます。必要に応じて別のデコレータを渡すことができるように、私は私のものを分割しました。