擅长:python、mysql、java
<p>这里有一个简单的(略显初级的;-)方法来跟踪“谁试图导入什么”的模块名:</p>
<pre><code>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
</code></pre>
<p>例如,它给出了(保存为<code>tracimp.py</code>):</p>
<pre><code>$ python -c 'import tracimp; import email; import sys; import email.mime'
email __main__
sys email
email.mime email
sys __main__
email.mime __main__
</code></pre>
<p>如您所见,“包装”内置的<code>__import__</code>的一个特定特征是,它不会因为正在导入的模块已经在<code>sys.modules</code>中而沉默:因为处理这是<code>__import__</code>的工作之一,我们的包装器被调用为“第一次加载”<strong>和</strong>两个模块,这两个模块将从<code>sys.modules</code>获取,因为它们以前已经被导入。当您试图诊断循环导入时,这应该非常有用(它可以归结为在有向图中查找循环,循环的边由两个模块名标识(imported和importer),这个简单的方法是在每个输出行上打印这两个模块名)。</p>