【发布时间】:2019-06-13 03:17:41
【问题描述】:
我正在使用“pyinstaller --onefile myapp.py”打包一个 python 应用程序,它会创建一个可执行文件,并且该应用程序运行良好。现在我希望能够从系统中导入一个模块(如果存在),否则使用单个可执行文件中的捆绑模块。如果安装了 PySide2,我特别想从系统导入 PySide2,理想情况下,它带有一个可配置的标志,指示应用程序是从系统加载还是从单个可执行文件加载。我已经在使用由单个可执行文件读取的配置文件,因此我可以在其中放置一个标志来指示如何加载模块。有没有办法做到这一点?
伪代码是这样的:
read import_external from configuration file
if import_external is true:
try:
import PySide2 from system
except:
import PySide2 from executable
编辑我正在接近解决方案。我可以从 pyinstaller onefile 可执行文件中动态导入单个 Python 文件,如下面的代码所示,我使用简单的打印语句创建了一个虚拟“PySide2.py”文件来验证它是否已导入。
import os
print("Import test")
if os.path.isfile('./PySide2.py'):
print('Importing local PySide2')
import importlib
import importlib.util
spec = importlib.util.spec_from_file_location('PySide2', './PySide2.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
else:
print('Importing system PySide2')
import PySide2
print(PySide2.__version__)
print("Import complete")
但是 PySide2 不是单个文件,所以现在我需要了解如何从目录导入。任何建议表示赞赏!
EDIT 2我在这里找到了解决方案:Python use importlib to import a module from a package directory
【问题讨论】:
-
PyInstaller 安装自己的 Python 解释器,如果有的话,它与已经安装的解释器是分开的。我认为你不能(或者你不应该)尝试从另一个 Python 安装中导入包。
-
感谢您指出单独的解释器。我没有想到这一点。不如先搜索本地目录看看是否可以从那里导入?用户必须注意版本是否兼容。
-
如果你必须这样做,你应该看看
importlib -
我不确定你为什么要这样做,因为 pyinstaller 的目的是将 py 文件转换为 exe。但是,如果您想在运行时导入外部模块(指出 Python 已安装在目标机器上),为什么要首先使用 pyinstaller?只需使用您的脚本。
-
我之所以这样做是为了遵守 PySide2 的 LGPL 许可。据我了解,使用 LGPL 库的作品必须分发源代码或使最终用户能够用不同的库替换 LGPL 库(他们有责任确保与API/函数调用/等)。如果我用 pyinstaller 创建了一个封闭的包,那么最终用户没有办法换掉 PySide2,这似乎违反了许可。
标签: python import module pyinstaller