I created a Python module with a single function that just prints 'a!'. I opened up the Python interpreter and imported the module in 2 different syntaxes
>>> import a
>>> from a import func
>>> func()
a!
>>> a.func()
a!
At this point I changed func to print something else, then evaluates again
>>> func()
a!
>>> a.func()
a!
This is expected of course as the module was not reloaded. Then I reloaded the module and expected both functions to update, however:
>>> reload(a)
<module 'a' from 'a.py'>
>>> a.func()
aasd!
>>> func()
a!
Only a.func seems to update. I always thought that Python keeps only a single instance of the same module, but now there appears to be two. I did further testing in order to verify my claim, and added a print statement at top level of the module, then restarted the interpreter and imported again:
>>> import a
module imported
>>> import a
>>> from a import func
This confuses me even more as I expected to see 'module imported' twice. The third experiment that I did was the global variable experiment:
>>> import a
module imported
>>> from a import GLOBAL_VAR
>>> GLOBAL_VAR = 5
>>> a.GLOBAL_VAR
1
>>> GLOBAL_VAR
5
>>> GLOBAL_VAR is a.GLOBAL_VAR
False
So there's a single instance of the module, but different instances of the objects inside? How is it possible to implement Gevent's monkey patching with such behaviour?
A module, once it's imported, is just another python object. So seeing the following example, your results should not surprise you at all:
When you do
from module import name
, a variablename
is created in the current namespace which holds a reference to the imported thing (be it a package/module/class/whatever). It's syntactic sugar for the following:Now, when you reload
module
, you obviously don't update the referencename
holds.Concerning your second experiment, a module is cached in
sys.modules
after the import; subsequent imports will take advantage of the cache. Thus all code that is directly at the module level, like yourprint
, will only get executed on the first import.