在Python中获取调用函数模块的__name__

假设myapp/foo.py包含:

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

myapp/bar.py包含:

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

我想在这种情况下,调用函数的模块(这是'myapp.foo')的__name__属性设置为__name__ 。 如何才能做到这一点?

检查检查模块:

inspect.stack()将返回堆栈信息。

在函数内部, inspect.stack()[1]将返callback用者的堆栈。 从那里,你可以得到更多关于调用者的函数名称,模块等信息。

有关详细信息,请参阅文档:

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

另外,Doug Hellmann在他的PyMOTW系列中有一个很好的检查模块的写法:

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

编辑:这是一些代码,你想要什么,我想:

 def info(msg): frm = inspect.stack()[1] mod = inspect.getmodule(frm[0]) print '[%s] %s' % (mod.__name__, msg) 

面对类似的问题,我发现sys模块中的sys._current_frames()包含有趣的信息,可以帮助您,而不需要导入检查,至less在特定的用例中。

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

然后你可以使用f_back“上移”

 >>> f = 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__' 

对于文件名,您也可以使用f.f_back.f_code.co_filename,如上面Mark Roddy所build议的。 我不确定这个方法的限制和注意事项(multithreading很可能是一个问题),但我打算在我的情况下使用它。

我不build议这样做,但是你可以用下面的方法完成你的目标:

 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)