Merge pull request #2224 from InfinityPacer/main

This commit is contained in:
jxxghp 2024-05-29 23:06:31 +08:00 committed by GitHub
commit 882da68903
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -18,7 +18,7 @@ class ModuleHelper:
导入模块 导入模块
:param package_path: 父包名 :param package_path: 父包名
:param filter_func: 子模块过滤函数入参为模块名和模块对象返回True则导入否则不导入 :param filter_func: 子模块过滤函数入参为模块名和模块对象返回True则导入否则不导入
:return: :return: 导入的模块对象列表
""" """
submodules: list = [] submodules: list = []
@ -46,27 +46,47 @@ class ModuleHelper:
导入子模块 导入子模块
:param package_path: 父包名 :param package_path: 父包名
:param filter_func: 子模块过滤函数入参为模块名和模块对象返回True则导入否则不导入 :param filter_func: 子模块过滤函数入参为模块名和模块对象返回True则导入否则不导入
:return: :return: 导入的模块对象列表
""" """
submodules: list = [] submodules: list = []
packages = importlib.import_module(package_path) 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: try:
if package_name.startswith('_'):
continue
full_package_name = f'{package_path}.{package_name}'
module = importlib.import_module(full_package_name) module = importlib.import_module(full_package_name)
# 预检查模块中的对象 # 预检查模块中的对象
candidates = [(name, obj) for name, obj in module.__dict__.items() if candidates = [(name, obj) for name, obj in module.__dict__.items() if
not name.startswith('_') and isinstance(obj, type)] not name.startswith('_') and isinstance(obj, type)]
# 确定是否需要重新加载 # 确定是否需要重新加载
if any(filter_func(name, obj) for name, obj in candidates): if any(filter_func(name, obj) for name, obj in candidates):
importlib.reload(module) submodules.extend(reload_module_objects(module))
# reload后对象已经发生变更重新过滤已经重新加载后的模块中的对象 # 如果子模块是包,重新加载其子模块
for name, obj in module.__dict__.items(): if is_pkg:
if not name.startswith('_') and isinstance(obj, type) and filter_func(name, obj): reload_sub_modules(module, full_package_name)
submodules.append(obj)
except Exception as err: except Exception as err:
logger.debug(f'加载模块 {package_name} 失败:{str(err)} - {traceback.format_exc()}') logger.debug(f'加载模块 {package_name} 失败:{str(err)} - {traceback.format_exc()}')