114

含まれていると仮定しmyapp/foo.pyます:

def info(msg):
    caller_name = ????
    print '[%s] %s' % (caller_name, msg)

そしてmyapp/bar.py含まれています:

import foo
foo.info('Hello') # => [myapp.bar] Hello

この場合、呼び出し元の関数'モジュール(' myapp.foo')の属性にcaller_name設定したいと思います。__name__これはどのように行うことができますか?

4

3 に答える 3

143

inspect モジュールをチェックアウトします。

inspect.stack()スタック情報を返します。

関数内ではinspect.stack()[1]、呼び出し元のスタックが返されます。そこから、呼び出し元の関数名、モジュールなどに関する詳細情報を取得できます。

詳細については、ドキュメントを参照してください。

http://docs.python.org/library/inspect.html

また、Doug Hellmann は PyMOTW シリーズで inspect モジュールの素晴らしい記事を書いています:

http://pymotw.com/2/inspect/index.html#module-inspect

編集:これはあなたが望むことをするいくつかのコードです、私は思います:

import inspect 

def info(msg):
    frm = inspect.stack()[1]
    mod = inspect.getmodule(frm[0])
    print '[%s] %s' % (mod.__name__, msg)
于 2009-07-08T01:03:42.510 に答える
24

同様の問題に直面して、sys モジュールのsys._current_frames()には、少なくとも特定のユースケースでは、inspect をインポートする必要なく役立つ興味深い情報が含まれていることがわかりました。

>>> sys._current_frames()
{4052: <frame object at 0x03200C98>}

次に、 f_back を使用して「上に移動」できます。

>>> f = sys._current_frames().values()[0]
>>> # for python3: f = list(sys._current_frames().values())[0]

>>> print f.f_back.f_globals['__file__']
'/base/data/home/apps/apricot/1.6456165165151/caller.py'

>>> print f.f_back.f_globals['__name__']
'__main__'

上記の Mark Roddy が提案したように、ファイル名には f.f_back.f_code.co_filename を使用することもできます。この方法の制限と注意事項はよくわかりませんが (複数のスレッドが問題になる可能性が高い)、私の場合は使用するつもりです。

于 2011-02-21T21:35:29.210 に答える
3

これを行うことはお勧めしませんが、次の方法で目的を達成できます。

def caller_name():
    frame=inspect.currentframe()
    frame=frame.f_back.f_back
    code=frame.f_code
    return code.co_filename

次に、既存のメソッドを次のように更新します。

def info(msg):
    caller = caller_name()
    print '[%s] %s' % (caller, msg)
于 2009-07-08T01:32:12.330 に答える