【问题标题】:Can I tell PyInstaller to package my entire source tree?我可以告诉 PyInstaller 打包我的整个源代码树吗?
【发布时间】:2016-02-02 09:09:47
【问题描述】:

目前我的 PyInstaller 规范如下所示:

导入系统 导入操作系统 重新进口 从路径库导入路径 调试 = 真 lib = 路径(“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) 对于索引,枚举中的路径(hidden_​​imports): 路径 = re.sub(r"lib(\\|\/)", "", 路径) 如果路径中有“__init__.py”: 路径 = re.sub(r"(\\|\/)__init__.py", "", 路径) 别的: 路径 = re.sub(r"\.py", "", 路径) hidden_​​imports[index] = ".".join(re.split(r"\\|\/", path)) block_cipher = 无 一=分析( [“app.pyw”], pathex=["lib"], 二进制文件=无, 数据=[ (“图标/*”,“图标”) ], hiddenimports=hidden_​​imports, hookspath=无, runtime_hooks=无, 排除=无, win_no_prefer_redirects=无, win_private_assemblies=无, 密码=block_cipher ) pyz = PYZ( a.pure,a.zipped_data, 密码=block_cipher ) 执行程序 = 执行程序( 皮兹, a.脚本, a.二进制文件, a.zip 文件, a.数据, 名称=“阿尔法”, 调试=调试, 条=无, upx=真, 控制台=调试, 图标="图标\\foo.ico" )

丑得要命,对吧?

我的源代码树中有一些目录,其文件名遵循特定的命名约定,并使用importlib 按需导入。出于显而易见的原因,我不想将所有这些模块的名称硬编码到我的规范中。

当使用“hiddenimports”选项时,参数必须是模块名称列表,因此我必须glob 获取文件名,遍历结果列表并“修改”文件名,同时考虑到 Windows和 Linux 支持。

必须有更好的方法。有什么方法可以告诉 PyInstaller 只包含我的整个源代码树,即lib/alpha 下的每个文件?

【问题讨论】:

    标签: python pyinstaller python-3.5


    【解决方案1】:

    您可以使用Tree() function 包含整个目录树,但这并不完全符合您的要求。由于您要添加源文件,因此您将希望 PyInstaller 递归地分析它们以进行导入,以确保包含它们的所有依赖项。最好的方法是通过 hiddenimports。

    我不会详细解释,而是从我自己的规范文件中分享一个 sn-p,我用它来包含我的应用程序不直接包含的模块,但提供给用户创建的插件使用。这非常适合您的用例。

    # 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)
    

    【讨论】:

    • 等一下。我想我可以为此使用collect_submodules。它通常被 hookfiles 用来收集导入库的子模块,但它也应该可以在 specfile 中使用。
    猜你喜欢
    • 2015-07-30
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 2020-02-21
    相关资源
    最近更新 更多