python - 我可以告诉 PyInstaller 打包我的整个源代码树吗?

目前我的 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/

相关文章:

r - PCA分析中不同类型的椭圆

image - 如何在 MATLAB 中将图像变形为梯形

visual-studio-2015 - VS2015数据库项目: Turn off schema

angularjs - 如何在 git 存储库中拆分 Angular 应用程序客户端/服务器端代码

bash - IntelliJ 14 Linux,无法识别环境变量

java - 如何直接在 android 中从 HashMap 设置对象字段

r - 使用 ggplot2 将不同的图像插入到单个面板中

curl - Jenkins 工作失败,无法从 curl 获得非 200 响应

amazon-web-services - 如何将 AWS SecureTokenService 与

web-services - 未确认电子邮件但成功登录的 REST API Http 状态代码