Reputation: 73
Is there a way to import a package twice in the same python session, under the same name, but at different scope, in a multi-threaded environment ?
I would like to import the package, then override some of its functions to change its behavior only when used in specific class.
For instance, is it possible to achieve something like this ?
import mod
class MyClass:
mod = __import__('mod')
def __init__():
mod.function = new_function # override module function
def method():
mod.function() # call new_function
mod.function() # call original function
It might seem weird, but in this case the user deriving the class wouldn't have to change his code to use the improved package.
Upvotes: 4
Views: 467
Reputation: 11590
It looks like a job for a context manager
import modul
def newfunc():
print('newfunc')
class MyClass:
def __enter__(self):
self._f = modul.func
modul.func = newfunc
return self
def __exit__(self, type, value, tb):
modul.func = self._f
def method(self):
modul.func()
modul.func()
with MyClass() as obj:
obj.method()
modul.func()
modul.func()
outputs
func
newfunc
newfunc
func
where modul.py
contains
def func():
print('func')
NOTE: this solution suits single-threaded applications only (unspecified in the OP)
Upvotes: 1
Reputation: 1733
To import a module as a copy:
def freshimport(name):
import sys, importlib
if name in sys.modules:
del sys.modules[name]
mod = importlib.import_module(name)
sys.modules[name] = mod
return mod
Test:
import mymodule as m1
m2 = freshimport('mymodule')
assert m1.func is not m2.func
Note:
importlib.reload
will not do the job, as it always "thoughtfully" updates the old module:
import importlib
import mymodule as m1
print(id(m1.func))
m2 = importlib.reload(m1)
print(id(m1.func))
print(id(m2.func))
Sample output:
139681606300944
139681606050680
139681606050680
Upvotes: 2