Step 1: assume this is the changing module, named test_module.py:
#coding=utf8
# changing module
class hello(object):
pass
"""
class world(object):
pass
"""
Step 2: dynamically reload the changing module
, named dynamis_changing_import.py:
"""
@note: Dynamicly import changing module
"""
__author__ = 'k9 Lee'
import sys
import importlib
"""
@important: Does not consider thread safty
"""
def dy_import(name, package=None):
# Fast path: see if the module has already been imported.
# @doc: imp
try:
sys.modules[name]
except KeyError:
# if not found, just import
importlib.import_module(name, package)
else:
# del and reload module
print '1'
del sys.modules[name]
print '2'
#importlib.import_module(name, package)
#print '3'
Step 3: test in ipython,
then I found sys.modules['test_module']
raise key error that means I can re-import test_module,
but I still can dir(test_module)
...
In [1]: import test_module
In [2]: dir(test_module)
Out[2]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']
In [3]: import dynamis_changing_import
In [4]: dynamis_changing_import.dy_import('test_module')
1
2
In [5]: import sys
In [6]: sys.modules['test_module'] # Here, test_module does not exist.
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-6-d2451de5c425> in <module>()
----> 1 sys.modules['test_module']
KeyError: 'test_module'
In [7]: dir(test_module) # But... dir... is still there...
Out[7]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']
Step 4. still test ipython:
I uncomment the last two statement in file dynamis_changing_import.py
,
importlib.import_module(name, package)
print '3'
and importlib.import_module
has no effect, I restart ipython:
In [1]: import sys
In [2]: import dynamis_changing_import
In [3]: import test_module
In [4]: dir(test_module)
Out[4]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']
In [5]: # Uncomment the method `world` in test_module
In [6]: dynamis_changing_import.dy_import('test_module')
1
2
3
In [7]: dir(test_module)
Out[7]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']
Thank you.
Do not mess with sys.modules
. That's a very low-level detail.
To safely reload a module you can simply:
reload
built-in function in python2imp.reload
on python3.x with 0 <= x < 4importlib.reload
in python3.4+For a cross-version solution simply do:
import sys
if sys.version_info.major == 3:
if sys.version_info.minor < 4:
from imp import reload
else:
from importlib import reload
When you want to re-import module X
you simply do:
reload(X)
So the "dynamic import" becomes:
import moduleX
And whenever you need the module to be reloaded you can just do:
reload(moduleX)
Sample run:
$ echo 'def f():print("a")
> f()' > t.py
$ python2
>>> import t
a
>>> t.f()
a
# in an other shell:
# $ echo 'def f():print("b")
# > f()' > t.py
>>> reload(t)
b
>>> t.f()
b