如何在使用pyinstaller的应用程序构建中加载插件?

时间:2019-06-07 14:02:18

标签: python pyinstaller

我有一个Python应用程序,可在运行时将插件作为模块加载。

module = importlib.import_module("plugins." + modulename)

现在,我想使用pyinstaller构建可执行文件,但是在运行时,我得到了ModuleNotFoundError。如何处理动态模块加载。请注意,这些插件/模块在构建过程中不可用。

编辑:添加了一些示例代码
interface.py

class Plugin:
    def __init__(self):
        pass

    def doSomethingUsefull(self, a, b):
        pass

main.py

import inspect
import pathlib
import os
from interface import Plugin
from importlib import import_module

def loadPlugins():
        plugins_dir = os.path.join(os.getcwd(), "plugins")
        for root, dirs, files in os.walk(plugins_dir):
            for file in files:
                modulename, ext = os.path.splitext(file)
                if ext == ".py":
                    module = import_module("plugins." + modulename)
                    for name, klass in inspect.getmembers(module, inspect.isclass):
                        if klass.__module__ == "plugins." + modulename:
                            instance = klass()
                            if isinstance(instance, Plugin):
                                print("Plugin Call:", instance.doSomethingUsefull(3, 5))
            break # not to list __pycache__ etc

loadPlugins()

plugins / test.py

from interface import Plugin

class TestPlugin(Plugin):
    def __init__(self):
        pass

    def doSomethingUsefull(self, a, b):
        return a * b

创建可执行文件后出现此错误:

Traceback (most recent call last):
  File "main.py", line 24, in <module>
    loadPlugins()
  File "main.py", line 15, in loadPlugins
    module = import_module("plugins." + modulename)
  File "importlib/__init__.py", line 126, in import_module
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 941, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'plugins'
[3451] Failed to execute script main

这里也是一棵树:

.
├── interface.py
├── main
├── main.py
├── main.spec
└── plugins
    └── test.py  

当我使用python3 main.py运行该应用程序时,得到以下输出:

Plugin Call: 15

1 个答案:

答案 0 :(得分:0)

幸运的是我找到了解决方案。 我忘了提及我为pyinstaller使用了--onefile选项,其中应用程序正在sys._MEIPASS中而不是os getcwd()中查找模块。 当我不使用--onefile时,一切正常。