As described here, in python it is possible to replace a current module implementation using sys.modules
:
import somemodule
import sys
del sys.modules['somemodule']
sys.modules['somemodule'] = __import__('somefakemodule')
But it doesn't work if import somemodule
is done in the code of another imported module:
In this example:
CustomModule
import somemodule
def f():
print(somemodule.someFunction())
ClientCode
from CustomModule import f
import sys
del sys.modules['somemodule']
sys.modules['somemodule'] = __import__('somefakemodule')
f() #Will use `somemodule.someFunction`
The call to f
will use somemodule.someFunction
, not somefakemodule.someFunction
Is it possible to make CustomModule
replace its use of somemodule
for somefakemodule
without changing its code? That is, from ClientCode
.
So each module is imported only one time. To better understand import mechanics I would suggest to create toy example. So import really happens only once. You can adjust this toy example to check cases that are interesting to you.
The rules are quite simple: the same module is evaluated only once, in other words, the module-level scope is executed just once. If the module, once evaluated, is imported again, it's second evaluation is skipped and the resolved already exports are used.
When a module is first imported, Python searches for the module and if found, it creates a module object 1, initializing it. If the named module cannot be found, a ModuleNotFoundError is raised. Python implements various strategies to search for the named module when the import machinery is invoked.
A module is loaded only once, regardless of the number of times it is imported. This prevents the module execution from happening over and over again if multiple imports occur.
Replace somemodule
with somefakemodule
before importing CustomModule
:
import sys
del sys.modules['somemodule']
sys.modules['somemodule'] = __import__('somefakemodule')
from CustomModule import f
That way, when CustomModule
executes
import somemodule
Python will find somemodule
in sys.modules
and return the cached module, somefakemodule
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With