当前位置: 首页 > news >正文

python动态加载插件 - ling

获取当前脚本路径

根据当前位置获取绝对路径,区分打包后的可执行文件开发环境

def get_plugins_dir(relative_path: str = "plugins") -> str:"""获取应用程序的插件目录如果是打包后的exe,返回exe所在目录如果是脚本,返回脚本所在目录"""if getattr(sys, "frozen", False):# 打包后的exepos = os.path.dirname(sys.executable)else:# 开发环境pos = os.path.dirname(os.path.abspath(__file__))pos = os.path.join(pos, relative_path)if not os.path.exists(pos):os.makedirs(pos)# 可选添加示例插件return pos

加载环境变量

使用闭包,允许热加载功能

def make_env_manager():"""设置动态加载包的环境变量"""env_path = []def inner(full_path: str):nonlocal env_path# 清空for path in list(env_path):sys.path.remove(path)# 记录环境路径env_path.append(os.path.dirname(full_path))for root, dirs, files in os.walk(full_path):if root not in sys.path:env_path.append(root)# 添加for path in env_path:sys.path.insert(0, path)return inner

加载插件

区分加载单个文件

def load_file(file_path: str, validate_func: Optional[Callable] = None):"""加载单个插件文件"""def validate_plugin(module):if not hasattr(module, "execute"):sys.modules.pop(module)raise ImportError(f"插件 {name} 缺少 execute() 函数")return Trueif validate_func is None:validate_func = validate_plugintry:name = os.path.splitext(os.path.basename(file_path))[0]spec = importlib.util.spec_from_file_location(name, file_path)if spec is None:raise ImportError(f"无法从文件创建模块规范: {file_path}")module = importlib.util.module_from_spec(spec)sys.modules[name] = modulespec.loader.exec_module(module)return module if validate_func(module) else Noneexcept Exception as e:# log errortraceback.print_exc()return Nonedef load_package(package_path: str, validate_func: Optional[Callable] = None):"""加载单个插件包"""def validate_plugin(module):if not hasattr(module, "execute"):sys.modules.pop(module)raise ImportError(f"插件 {name} 缺少 execute() 函数")return Trueif validate_func is None:validate_func = validate_plugintry:name = os.path.basename(package_path)if package_path not in sys.path:sys.path.insert(0, package_path)module = importlib.import_module(name)if validate_func(module):return moduletry:main_module = importlib.import_module(f"{name}.main")return main_module if validate_func(main_module) else Noneexcept ImportError:raise ImportError(f"插件包 {name} 中未找到可用的主模块")except Exception as e:traceback.print_exc()return None

获取所有插件

根据传入路经筛选插件

def scan_plugins(path: str) -> list[str]:file_ans = list(filter(lambda x: x != "",map(lambda name: (os.path.join(path, name)if not name.startswith(".")and not name.startswith("__")and os.path.splitext(name)[1] in [".py", ""]else ""),os.listdir(path),),))return file_ans

Example

  1. 获取插件文件夹路径

  2. 获取所有插件

  3. 加载环境变量

  4. 加载插件

if __name__ == "__main__":base_path = get_plugins_dir()p = scan_plugins(base_path)env_manager = make_env_manager()env_manager(base_path)loaded_plugins = load_plugins(p)print(loaded_plugins)
http://www.gsyq.cn/news/33984.html

相关文章:

  • 实用指南:C++设计模式_结构型模式_适配器模式Adapter
  • rbd元数据
  • 2025年不锈钢编织绳网柔性加工厂权威推荐榜单:不锈钢编织绳网围网/不锈钢手工编织绳网/焊接不锈钢编织绳网源头厂家精选
  • onBeforeMount 和 onMounted区分总结
  • Linux应用(6)——网络通信/TCP/IP - 详解
  • 2025 年 pe 板源头厂家最新推荐榜,技术实力与市场口碑深度解析,精选优质企业pp 板 pe 板/耐腐蚀 pe 板/耐磨 pe 板公司推荐
  • 关于如何解决HP笔记本键盘失灵的方法
  • ({behavior: smooth}) 在移动端不生效的问题解决 ios不平滑,使用smoothscroll-polyfill(页面平滑滚动)插件
  • ArkTS语言(三)
  • [转] 封装超时工具方法
  • 2025年激光熔覆涂层制造厂权威推荐:熔覆激光/高速激光熔覆/激光熔覆源头厂家精选
  • 学术会议会议合集 | 大数据、智慧医学 、数据管理 、计算机科学 、管理科学等EI会议合集
  • K8S使用开源CEPH作为后端StorageClass
  • 2025 年锅炉厂家最新推荐榜:智能控制与稳定可靠品牌综合测评结果及优质厂商名单电锅炉/蒸汽锅炉/燃气锅炉/燃油锅炉/电蒸汽锅炉公司推荐
  • Python自动化之Docx文档处理(二)
  • 探索Go语言性能优化:全面解析pprof工具
  • Bcache详解及踩坑记录
  • 什么是跨网域资源共享(CROS)
  • 从经验到数据:MyEMS 如何推动能源管理的范式升级?
  • 2025 年试压泵厂家最新推荐榜,技术实力与市场口碑深度解析,展现国产设备卓越性能四缸电动/三缸电动/水管/大流量电动/柴油动力试压泵公司推荐
  • Ceph运维手册(基于P版本)
  • 完整教程:金融分析师技能提升路径与学习资源指南
  • Unreal:如何调用DLL
  • MyEMS 的智慧大脑:从能耗建模到预测性维护的全流程技术逻辑
  • CentOS7下OpenSSH10.0p2升级实践
  • 2025年美国威盾VTON进口分体式流量计生产厂家权威推荐:美国威盾VTON进口气体流量计/美国威盾VTON进口流量计/美国威盾VTON进口旋进漩涡流量计源头供应商精选
  • 2025年塑料瓶灌装机优质厂家权威推荐榜单:液体灌装旋盖机/灌装旋盖机/膏液两用灌装机源头厂家精选
  • Linux-按下开机键后,究竟发生了什么
  • K8s v1.2到v1.34:从容器编排到 AI/ML 的云原生未来
  • ASP.NET Core Web API 需要先发布到 IIS 服务器才能运行