Вы могли бы попробовать реализовать глубокую функцию повторной загрузки путем проверки модуль для перезагрузки и перезагрузки любых модулей оно использует. Это не является надежным, например, не справится с чем-то вроде:
class MyClass:
module = import_module('amodule')
, но вполне может быть достаточно для ваших целей.
mymod.py
# Example submodule to re-import
print('import module mymod')
# demonstrate we can even import test as a module and it works
import sys
from test import deep_reload_module
value = 2
def a_function():
pass
class XYZ:
pass
class NewClass(object):
pass
test.py
import importlib
import sys
import mymod
def deep_reload_module(name):
mod = sys.modules.get(name)
if not mod:
importlib.import_module(name)
return
def get_mods_to_reload_recursively(name, modules_to_reload=None):
modules_to_reload = modules_to_reload or set()
mod = sys.modules[name]
modules_to_reload.add(name)
# loop through the attributes in this module and remember any
# submodules we should also reload
for attr in dir(mod):
prop = getattr(mod, attr)
if isinstance(prop, type(mymod)):
modname = attr
elif hasattr(prop, '__module__'):
modname = prop.__module__
if not modname:
continue
else:
# this thing is not a module nor does it come from another
# module, so nothing to reimport.
continue
if modname in sys.builtin_module_names:
# probably best not to reimport built-ins...
continue
if modname in modules_to_reload:
# this is already marked for reimporting, so avoid infinite
# recursion
continue
# get_mods_to_reload... will update modules_to_reload so no need to
# catch the return value
get_mods_to_reload_recursively(modname, modules_to_reload)
return modules_to_reload
mods_to_reload = get_mods_to_reload_recursively(name)
for mtr in mods_to_reload:
# best to delete everything before reloading so that you are
# sure things get re-hooked up properly to the new modules.
print('del sys.modules[%s]' % (mtr,))
del sys.modules[mtr]
importlib.import_module(name)
if __name__ == '__main__':
orig_mymod_id = id(sys.modules['mymod'])
deep_reload_module('mymod')
assert orig_mymod_id != id(sys.modules['mymod'])
Тогда вам просто нужно позвонить deep_reload_module('module')
всякий раз, когда начинается новый процесс, или еще проще в начале каждого многопроцессорной работы.
NB: это полагается довольно сильно на коде, который живет за пределами модуля, который вы хотите реимпортировать ранее не имея импортируемое ничего из этого модуля, потому что если у него есть то, что код будет продолжать использовать старый модуль или сломаться.
E.g. если у вас есть код, который делает это:
from module_to_reimport import a_function
Но не сохранили module_to_reimport
где-либо в явном виде, то a_function
вполне может терпеть неудачу, когда он вызывается после того, как модуль реимпорта, поскольку он поддерживает только слабую ссылку на globals()
определенные в module_to_reimport
, и все они будут уничтожены путем удаления модуля с sys.modules
.
Похожие темы: https://bytes.com/topic/python/answers/22688-multiple-instances-modules –
Спасибо Xin, но ответы на эту тему предполагают, что вы написали данный модуль. Тот, который рассматривается здесь, - это одно плохо написанное - с состоянием в модулях вместо классов. – er0