开发者

How can I track python imports [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed 3 years ago.

Improve this question

I have cyclical import issues adding some new code to a very large app, and I'm trying to determine which files are the most likely causes for this. It there any way to track which files import which files? I did a bit of looking and found the python trace command, but it's just showing a bunch of activity in the main python libraries.

I'm basically looking for an app that will show me something like:

App1 >>imports>> App2,App3.method
App2 >>im开发者_StackOverflow社区ports>> App3,etc

I could just look through all of my files, but I'd rather not, it's a big app.


Here's a simple (and slightly rudimentary;-) way to trace "who's trying to import what" in terms of module names:

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

which gives, for example (having saved this as 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__

As you see, one specific characteristic of "wrapping" the __import__ built-in is that it won't be silenced by the fact that a module being imported is already in sys.modules: since taking care of that is one of __import__'s jobs, our wrapper gets called for both modules "being loaded for the first time" and ones that are just going to get fetched from sys.modules because they were already imported previously. This should come in really handy when you're trying to diagnose circular imports (it boils down to finding loops in the directed graph whose edges are identified by the two module names -- imported and importer -- which this simple approach is printing on each output line).


You could use one of these scripts to make python module dependency graphs:

  • http://furius.ca/snakefood/
  • http://www.tarind.com/depgraph.html
  • http://code.activestate.com/recipes/535136/


Try using python -v to run your program. It will trace the sequence of imports.

Another option is pylint, which will alert you to all sorts of issues, including cyclic imports.


It shouldn't be possible to get a cyclic import in python because it checks if the module has already been imported before importing it again. You can only import a module once, no matter how many times you call import.

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

Imports are pretty straightforward really. Just remember the following:

'import' and 'from xxx import yyy' are executable statements. They execute when the running program reaches that line.

If a module is not in sys.modules, then an import creates the new module entry in sys.modules and then executes the code in the module. It does not return control to the calling module until the execution has completed.

If a module does exist in sys.modules then an import simply returns that module whether or not it has completed executing. That is the reason why cyclic imports may return modules which appear to be partly empty.

Finally, the executing script runs in a module named __main__, importing the script under its own name will create a new module unrelated to __main__.

Take that lot together and you shouldn't get any surprises when importing modules.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜