[英]Importing external module in single-file exe created with PyInstaller
I am using PyInstaller to create a single-file executable.我正在使用 PyInstaller 创建一个单文件可执行文件。 Is it possible for my script to perform an import such that i) the imported module is imported from the same directory as the exe (ie it's not packaged into the exe) and ii) that imported module can import other modules that were packaged into the exe?
是否有可能为我的脚本执行导入使得i)导入的模块是从同一个目录中的exe(即它不是打包成EXE)和ii)在导入模块可以导入被打包到其他模块中引入exe?
The background here is that the imported module contains configuration that the user should be able to modify.这里的背景是导入的模块包含用户应该能够修改的配置。 This may include creation of custom derived classes and use of enums from the packaged modules.
这可能包括创建自定义派生类和使用来自打包模块的枚举。
I haven't found any advice on this, though it's a difficult search because there are so many similar topics that use basically the same keywords.我没有找到任何关于此的建议,尽管搜索起来很困难,因为有太多使用基本相同关键字的相似主题。
The following steps allow a Python module (named module_name
here) outside of an executable created by PyInstaller to be imported and for that module to import modules that were bundled into the executable.以下步骤允许导入 PyInstaller 创建的可执行文件之外的 Python 模块(此处名为
module_name
),并允许该模块导入捆绑到可执行文件中的模块。
excludes=['module_name']
to the Analysis object used in the PyInstaller spec.excludes=['module_name']
添加到 PyInstaller 规范中使用的 Analysis 对象。 This prevents module_name.py
being bundled into the executable.module_name.py
被捆绑到可执行文件中。sys.path.append(os.path.dirname(sys.executable))
where module_name
is imported in your application.sys.path.append(os.path.dirname(sys.executable))
其中module_name
在您的应用程序中导入。 This allows it to be imported from the directory the executable is in, which is different to the directory that the application will run in (due to being decompressed to a temporary folder).sys.modules
.sys.modules
中已经存在的模块。 In order to set up the paths correctly you can use the following:为了正确设置路径,您可以使用以下内容:
if getattr(sys, 'frozen', False):
app_path = os.path.dirname(sys.executable)
sys.path.append(app_path)
else:
app_path = os.path.dirname(os.path.abspath(__file__))
frozen
is only available in generated executables, not when running as a script directly. frozen
仅在生成的可执行文件中可用,在直接作为脚本运行时不可用。 This snippet will add the executable's location to sys.path
if required as well as giving you easy access to the executable or script's location for use in code.如果需要,此代码段会将可执行文件的位置添加到
sys.path
,并让您轻松访问可执行文件或脚本的位置以在代码中使用。
As an example of the final bullet point, consider the following.作为最后一个要点的示例,请考虑以下内容。
# bundled_module1.py
import external_module
# bundled_module2.py
# module content
# external_module.py
import bundled_module2
This will fail in external_module.py
because the imported module can't be found.这将在
external_module.py
失败,因为无法找到导入的模块。 However, the following will work:但是,以下内容将起作用:
# bundled_module1.py
import bundled_module2
import external_module
# bundled_module2.py
# module content
# external_module.py
import bundled_module2
This will be fine if there are a limited set of bundled modules that the external one should be able to import.如果外部模块应该能够导入一组有限的捆绑模块,这将没问题。 It may get unwieldy for larger sets.
对于较大的集合,它可能会变得笨拙。
Given that the documentation states that the interpreter will resolve imports against modules bundled into the executable, this feels like a possible bug.鉴于文档指出解释器将针对捆绑到可执行文件中的模块解析导入,这感觉像是一个可能的错误。 Interoperating with modules outside of the executable isn't explicitly called out though.
与可执行文件之外的模块互操作虽然没有明确调用。
Type in Pyinstaller -h
.输入
Pyinstaller -h
。 It will give you info about pyinstaller and tell you about --runtime-hook
.它将为您提供有关 pyinstaller 的信息并告诉您有关
--runtime-hook
。 I presume adding this to the executable should work.我认为将此添加到可执行文件应该可以工作。 There's actually a whole page of documentation for this.
这实际上有一整页文档。 Surprised you could not find that.
很惊讶你找不到那个。
Anyway,反正,
The docs say put in: pyinstaller --additional-hooks-dir=. myscript.py
文档说放入:
pyinstaller --additional-hooks-dir=. myscript.py
pyinstaller --additional-hooks-dir=. myscript.py
. pyinstaller --additional-hooks-dir=. myscript.py
。
I presume then something like pyinstaller --additional-hooks-dir=C:\\pathtofolder myscript.py
should work in theory.我认为像
pyinstaller --additional-hooks-dir=C:\\pathtofolder myscript.py
这样的东西理论上应该可以工作。 Yet to test it.还是要测试一下。 Tell us how it goes and what made kinks made it work for you.
告诉我们它是怎么回事,是什么让扭结让它为你工作。
Lastly, if you want to be hipster try integrating cython for speed and obfuscation.最后,如果您想成为时髦人士,请尝试集成 cython 以提高速度和混淆。 Fair warning, cython is not as user friendly as pyinstaller appears to be.
公平警告,cython 不像 pyinstaller 看起来那么用户友好。 I have yet to use it successfully.
我还没有成功使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.