From 2798700f713d0b60ad90cb6f7ee3a61ba1fefdb9 Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Wed, 29 May 2024 23:01:58 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E6=8F=92=E4=BB=B6=E9=87=8D=E8=BD=BD?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E6=94=AF=E6=8C=81reload=E4=B8=80=E7=BA=A7?= =?UTF-8?q?=E5=AD=90=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helper/module.py | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/app/helper/module.py b/app/helper/module.py index ca3a422d..29c23797 100644 --- a/app/helper/module.py +++ b/app/helper/module.py @@ -18,7 +18,7 @@ class ModuleHelper: 导入模块 :param package_path: 父包名 :param filter_func: 子模块过滤函数,入参为模块名和模块对象,返回True则导入,否则不导入 - :return: + :return: 导入的模块对象列表 """ submodules: list = [] @@ -46,27 +46,47 @@ class ModuleHelper: 导入子模块 :param package_path: 父包名 :param filter_func: 子模块过滤函数,入参为模块名和模块对象,返回True则导入,否则不导入 - :return: + :return: 导入的模块对象列表 """ submodules: list = [] packages = importlib.import_module(package_path) - for importer, package_name, _ in pkgutil.iter_modules(packages.__path__): + + def reload_module_objects(target_module): + """加载模块并返回对象""" + importlib.reload(target_module) + # reload后,重新过滤已经重新加载后的模块中的对象 + return [ + obj for name, obj in target_module.__dict__.items() + if not name.startswith('_') and isinstance(obj, type) and filter_func(name, obj) + ] + + def reload_sub_modules(parent_module, parent_module_name): + """重新加载一级子模块""" + for sub_importer, sub_module_name, sub_is_pkg in pkgutil.walk_packages(parent_module.__path__): + full_sub_module_name = f'{parent_module_name}.{sub_module_name}' + try: + full_sub_module = importlib.import_module(full_sub_module_name) + importlib.reload(full_sub_module) + except Exception as sub_err: + logger.debug(f'加载子模块 {full_sub_module_name} 失败:{str(sub_err)} - {traceback.format_exc()}') + + # 遍历包中的所有子模块 + for importer, package_name, is_pkg in pkgutil.iter_modules(packages.__path__): + if package_name.startswith('_'): + continue + full_package_name = f'{package_path}.{package_name}' try: - if package_name.startswith('_'): - continue - full_package_name = f'{package_path}.{package_name}' module = importlib.import_module(full_package_name) # 预检查模块中的对象 candidates = [(name, obj) for name, obj in module.__dict__.items() if not name.startswith('_') and isinstance(obj, type)] # 确定是否需要重新加载 if any(filter_func(name, obj) for name, obj in candidates): - importlib.reload(module) - # reload后,对象已经发生变更,重新过滤已经重新加载后的模块中的对象 - for name, obj in module.__dict__.items(): - if not name.startswith('_') and isinstance(obj, type) and filter_func(name, obj): - submodules.append(obj) + submodules.extend(reload_module_objects(module)) + # 如果子模块是包,重新加载其子模块 + if is_pkg: + reload_sub_modules(module, full_package_name) except Exception as err: logger.debug(f'加载模块 {package_name} 失败:{str(err)} - {traceback.format_exc()}')