Если вам разрешено изменять источник целевого модуля, и он достаточно мал, я думаю, что самое чистое решение здесь - переписать его как класс.А затем импортируйте класс, унаследуйте его и настройте.
Также имейте в виду, что перезагрузка модулей в Python имеет много предостережений, это больше для игры в оболочке Python, чем для производственного кода.
На основена том, что вы сказали в комментарии, я немного изменил ваш код.Я использовал importlib
, потому что модуль imp устарел.Также обратите внимание, что «исправление обезьян» (именно так называется эта техника, вы хотите сделать исправление во время выполнения кода) всегда тесно связано с целевым кодом.Если есть изменения, ваш код патча может легко сломаться.
Я написал два файла module.py
и test_module.py
:
#-----------
# module.py
a = 100
b = 200
# returns something
def sum3(x,y):
return x + y + 3
# does something
def print_a_b():
global a
print(a,b)
a = a + 1 # test module reloads. If ok, "a" remains 100
#----------------
# test_module.py
import module
import importlib as imp
def get_method_with_extra(method_name, module):
def method_with_extra(self, *args):
imp.reload(module) # comment to see that "a" increases
func_to_call = getattr(module, method_name)
if args: # function may not have args
return func_to_call(*args)
else: # function may not have args
return func_to_call()
return method_with_extra
class tester():
def __init__(self, module_path):
self.module = imp.import_module('module', module_path)
method_list = [func for func in dir(self.module)
if callable(getattr(self.module, func))]
for method_name in method_list:
#print(method_name)
method_with_extra = \
get_method_with_extra(method_name, self.module)
setattr(type(self), method_name, method_with_extra)
t = tester('.')
print(t.sum3(1,2))
t.print_a_b()
t.print_a_b() # checking for the reload, "a" should be 100