目前我的 PyInstaller 规范如下所示:
import sys import os import re from pathlib import Path DEBUG = True lib = Path("lib/alpha") hidden_imports = [] hidden_imports += lib.glob("processes/**/*.py") hidden_imports += lib.glob("ui/config_panels/**/*.py") hidden_imports += lib.glob("ui/logic/**/*.py") hidden_imports = list(str(x) for x in hidden_imports) for index, path in enumerate(hidden_imports): path = re.sub(r"lib(\\|\/)", "", path) if "__init__.py" in path: path = re.sub(r"(\\|\/)__init__.py", "", path) else: path = re.sub(r"\.py", "", path) hidden_imports[index] = ".".join(re.split(r"\\|\/", path)) block_cipher = None a = Analysis( ["app.pyw"], pathex=["lib"], binaries=None, datas=[ ("icons/*", "icons") ], hiddenimports=hidden_imports, hookspath=None, runtime_hooks=None, excludes=None, win_no_prefer_redirects=None, win_private_assemblies=None, cipher=block_cipher ) pyz = PYZ( a.pure, a.zipped_data, cipher=block_cipher ) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name="alpha", debug=DEBUG, strip=None, upx=True, console=DEBUG, icon="icons\\foo.ico" )
太丑了吧?
我的源代码树中有一些目录,其文件名遵循特定的命名约定,并使用 importlib
按需导入。出于显而易见的原因,我不想将所有这些模块的名称硬编码到我的规范中。
当使用“hiddenimports”选项时,参数必须是模块名称列表,所以我必须 glob
文件名,遍历结果列表并“修改”文件名,考虑到 Windows 和 Linux 支持。
必须有更好的方法。有什么方法可以告诉 PyInstaller 仅包括我的整个 源代码树,即 lib/alpha
下的每个文件?
最佳答案
您可以使用 Tree()
function 包含整个目录树,但这并不能完全满足您的要求。由于您正在添加源文件,您将希望 PyInstaller 递归地分析它们以进行导入,以确保包含它们的所有依赖项。最好的方法是通过 hiddenimports。
我不会详细解释,而是分享我自己的规范文件中的一个片段,我用它来包含我的应用程序未直接包含但提供给用户创建的插件使用的模块。这非常适合您的用例。
# Files under mcedit2.synth are used only by plugins and not internally.
support_modules = []
for root, dirnames, filenames in os.walk(os.path.join('src', 'mcedit2', 'synth')):
for filename in fnmatch.filter(filenames, '*.py'):
if filename == "__init__.py":
filepath = root
else:
filepath = os.path.join(root, filename)
filepath = filepath[:-3] # discard ".py"
components = filepath.split(os.path.sep)
components = components[1:] # discard 'src/'
if "test" in components or components == ["mcedit2", "main"]:
continue
modulename = ".".join(components) # dotted modulename
support_modules.append(modulename)
hiddenimports.extend(support_modules)
https://stackoverflow.com/questions/33478388/