Suppose I have a module file like this:
# my_module.py
print("hello")
Then I have a simple script:
# my_script.py
import my_module
This will print "hello"
.
Let's say I want to "override" the print()
function so it returns "world"
instead. How could I do this programmatically (without manually modifying my_module.py
)?
What I thought is that I need somehow to modify the source code of my_module
before or while importing it. Obvisouly, I cannot do this after importing it so solution using unittest.mock
are impossible.
I also thought I could read the file my_module.py
, perform modification, then load it. But this is ugly, as it will not work if the module is located somewhere else.
The good solution, I think, is to make use of importlib
.
I read the doc and found a very intersecting method: get_source(fullname)
. I thought I could just override it:
def get_source(fullname):
source = super().get_source(fullname)
source = source.replace("hello", "world")
return source
Unfortunately, I am a bit lost with all these abstract classes and I do not know how to perform this properly.
I tried vainly:
spec = importlib.util.find_spec("my_module")
spec.loader.get_source = mocked_get_source
module = importlib.util.module_from_spec(spec)
Any help would be welcome, please.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…