如何知道谁在python中导入我?

时间:2011-10-24 04:32:08

标签: python import

如何在python中找出导入特定文件的文件?

考虑以下示例:

#a.py
import cmn
....

#b.py
import cmn
...

#cmn.py
#Here, I want to know which file (a.py or b.py)
#is importing this one.
#Is it possible to do this?
...

所有文件a.pyb.pycmn.py都位于同一目录中。

为什么我要这样做?
在C / C ++中,它们具有包含功能。我想做的事情可以通过C / C ++代码来阐明。

//a.cpp
....
#define SOME_STUFF   ....
#include "cmn.h"

//b.cpp
...
#define SOME_STUFF   ....

#include "cmn.h"

//cmn.h
//Here, I'll define some functions/classes that will use the symbol define
//in the a.cpp or b.cpp
...
....code refer to the SOME_STUFF.....

在C / C ++中,我们可以使用此方法重用sourecode。

现在返回我的python代码 当a.py导入cmn.py时,我希望运行cmn.py并且cmn.py将引用a.py中定义的符号。
当b.py导入cmn.py时,我希望运行cmn.py并且cmn.py将引用b.py中定义的符号。

3 个答案:

答案 0 :(得分:11)

集合模块中的 namedtuple 代码有一个示例,说明如何(以及何时)执行此操作:

#cmn.py
import sys
print 'I am being imported by', sys._getframe(1).f_globals.get('__name__')

此方法的一个限制是最外层模块始终命名为__main__。如果是这种情况,可以从sys.argv[0]确定最外层模块的名称。

第二个限制是,如果使用sys._getframe的代码在模块范围内,则仅在第一次导入cmn.py时执行。如果要监视模块的所有导入,则需要在导入后调用某种函数。

答案 1 :(得分:3)

嗯,这是一件奇怪的事情。您还没有解释为什么您想知道导入模块的内容,因此我实际上无法帮助您解决问题。您还没有解释您想知道导入模块的方式或时间。

def who_imports(studied_module):
    for loaded_module in sys.modules.values():
        for module_attribute in dir(loaded_module):
            if getattr(loaded_module, module_attribute) is studied_module:
                yield loaded_module

这将为您提供使用模块作为顶级对象的所有模块的迭代器。它找不到from cmn import *的模块,列表会随着时间而改变。

>>> import os
>>> for m in who_imports(os):
...     print m.__name__
... 
site
__main__
posixpath
genericpath
posixpath
linecache

答案 2 :(得分:1)

您需要安装跟踪所有导入的导入挂钩。见PEP 302和http://docs.python.org/dev/py3k/library/importlib.html。但是,正如上面的评论所指出的,可能有更好的方法来构建代码。