2009-11-28 213 views
18

我有周期性的导入问题,将一些新代码添加到一个非常大的应用程序中,我试图确定哪些文件是导致此问题的最可能原因。有没有办法跟踪哪些文件导入哪些文件?我查了一下,发现了python trace命令,但它只是在主python库中显示了一堆活动。如何跟踪python导入

我基本上寻找一个应用程序,会告诉我是这样的:

App1 >>imports>> App2,App3.method 
App2 >>imports>> App3,etc 

我可以通过我的所有文件只是看看,但我宁愿没有,这是一个很大的应用程序。

回答

-2

应该不可能在python中获得循环导入,因为它会在再次导入之前检查模块是否已经导入。无论您调用导入多少次,您都只能导入一次模块。

http://groups.google.com/group/comp.lang.python/browse_thread/thread/1d80a1c6db2b867c?pli=1

进口相当简单明了 真的。请记住以下内容:

'import'和'from xxx import yyy'是 可执行语句。当正在运行的程序到达 行时,它们执行 。

如果模块不在sys.modules中, 然后导入创建sys.modules中新模块 项,然后在模块中执行 代码。它不会将 返回到调用模块 直到执行完成。

如果一个模块并在sys.modules中 存在,那么进口仅仅返回 模块它是否已经完成 执行。这就是为什么 循环进口可能会返回模块 看起来部分是空的。

最后,执行脚本在运行 模块命名__main__,进口以自己的名义在 脚本将创建 无关 __main__一个新的模块。

把这个地段放在一起,你 不应该得到任何意外,当 导入模块。

+6

这是非常有可能得到循环进口。它们不会无限循环,但它们会在需要时未定义函数时产生问题,因为两个文件相互导入。 – 2009-11-28 00:22:54

+3

当你从一个模块中专门导入一个项目,并且另一个模块导入你时,python中的循环导入只是一个问题。如果你这样做: 在A.py:进口乙 在B.py:导入 然后,你会不会有问题,即使他们循环导入海誓山盟,因为引用推迟到进口的实际执行/使用项目。只有当您从另一个模块请求一个项目(即,在导入时请求一个参考)时,尚未定义这个项目会导致问题。 – 2013-02-23 09:32:19

9

尝试使用python -v来运行您的程序。它会跟踪进口的顺序。

另一种选择是pylint,它会提醒您各种问题,包括循环导入。

+3

我想在uwsgi下运行python的时候使用这个-v选项。我最终把这个添加到我的uwsgi ini文件中: 'env = PYTHONVERBOSE = 1' 然后输出进入正常的uwsgi日志文件中指定的内容。 – 2011-11-14 23:17:10

14

这里有一个简单(略简陋;-)方式追查“是谁在试图导入什么”,在模块名称方面:

import inspect 
import __builtin__ 
savimp = __builtin__.__import__ 

def newimp(name, *x): 
    caller = inspect.currentframe().f_back 
    print name, caller.f_globals.get('__name__') 
    return savimp(name, *x) 

__builtin__.__import__ = newimp 

赋予,例如(救以此为tracimp.py):

$ python -c 'import tracimp; import email; import sys; import email.mime' 
email __main__ 
sys email 
email.mime email 
sys __main__ 
email.mime __main__ 

正如你看到的,“包装”的__import__内置的一个具体特点是:它不会被一个事实,即模块被进口的沉默已经在sys.modules:因为照顾是__import__的工作之一,我们的包装被称为两个模块“第一次加载”,因为它们以前已经导入过,所以它们只会从sys.modules获取。当您尝试诊断循环导入时,这应该非常方便(它归结为在有向图中查找循环,其边界由两个模块名称 - 导入和导入器 - 这种简单方法在每个模块上打印输出线)。