Is there a way to do something (like print "funkymodule imported" for example) every time a module is imported from any other module? Not only the first time it's imported to the runtime or reloaded?
1 Answer 1
One possibility would be to monkey patch __import__:
>>> old_import = __import__
>>> def my_import(module,*args,**kwargs):
... print module, 'loaded'
... return old_import(module,*args,**kwargs)
...
>>> __builtins__.__import__ = my_import
>>> import datetime
datetime loaded
>>> import datetime
datetime loaded
>>> import django
django loaded
It worked fine on command line (using Python 2.7.3 on Windows XP), but I dunno if would work in other environments.
To access the module object (instead of just the module name - so you can do something useful with it) just intercept the return value instead of the argument:
>>> def my_import(*args,**kwargs):
... ret = old_import(*args,**kwargs)
... print ret
... return ret
...
>>> __builtins__.__import__ = my_import
>>> import datetime
<module 'datetime' (built-in)>
>>> import django
<module 'django' from 'C:\Python27\lib\site-packages\django\__init__.pyc'>
Update: Just confirmed it works if used inside a python file too - though in this case, the correct way of assigning it is __builtins__['__import__'] = my_import.
4 Comments
import module), no matter who is importing it. Even imports inside imports will work (though for the inner modules, only the first time will show it - since the module body is not run again).return old_import(*args,**kwargs) at the end after whatever extra stuff you wanted done (unless you wanted to do something afterwards, of course).
sys.moduleswith a custom mapping, reimplementing__getitem__, but the import machinery probably calls directlyPyDict_GetItemfrom the C side so even this shouldn't work.