代码之家  ›  专栏  ›  技术社区  ›  Kemp

在使用PyInstaller创建的单个文件exe中导入外部模块

  •  11
  • Kemp  · 技术社区  · 7 年前

    我正在使用PyInstaller创建一个可执行文件。我的脚本是否可以执行导入,以便i)导入的模块从与exe相同的目录导入(即,它没有打包到exe中),以及ii)导入的模块可以导入其他 打包到exe?

    这里的背景是,导入的模块包含用户应该能够修改的配置。这可能包括创建自定义派生类和使用打包模块中的枚举。

    我没有找到任何关于这方面的建议,虽然这是一个困难的搜索,因为有这么多类似的主题,使用基本相同的关键字。

    2 回复  |  直到 7 年前
        1
  •  14
  •   Kemp    3 年前

    以下步骤允许使用Python模块(名为 external_module 此处)在PyInstaller创建的要导入的可执行文件之外,并为该模块导入捆绑到可执行文件中的模块。

    • 添加 excludes=['external_module'] external_module.py 被捆绑到可执行文件中。
    • 添加 sys.path.append(os.path.dirname(sys.executable)) 哪里 外部_模块 在应用程序中导入。这允许将其从可执行文件所在的目录导入,该目录不同于应用程序将在其中运行的目录(由于被解压缩到临时文件夹)。下面是我推荐的实现方法。
    • 确保所有导入由 外部_模块。py公司 之前 外部_模块。py公司 已导入。口译员 不会 根据捆绑模块解析外部模块的导入,但是 使用中已经存在的 sys.modules .

    为了正确设置路径,您可以使用以下方法:

    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 仅在生成的可执行文件中可用,在直接作为脚本运行时不可用。此代码段将把可执行文件的位置添加到 sys.path 如果需要,还可以方便地访问可执行文件或脚本的位置,以便在代码中使用。

    作为最后一个要点的示例,请考虑以下内容。

    # bundled_module1.py
    import external_module
    
    # bundled_module2.py
    # module content
    
    # external_module.py
    import bundled_module2
    

    这将失败 外部_模块。py公司 因为 bundled_module2 找不到。但是,以下方法可行:

    # bundled_module1.py
    import bundled_module2
    import external_module
    
    #捆绑_模块2。py公司
    #模块内容
    
    #外部_模块。py公司
    导入捆绑_模块2
    

    如果有一组有限的捆绑模块,外部模块应该能够导入,那么这将很好。对于较大的集合,它可能会变得笨拙。

    鉴于文件说明口译员 根据捆绑到可执行文件中的模块解决导入问题,这感觉像是一个可能的bug。但是,与可执行文件之外的模块进行互操作并没有显式调用。

        2
  •  0
  •   Sheppardvines    7 年前

    Pyinstaller -h . 它将为您提供pyinstaller的信息,并告诉您 --runtime-hook . 我假设将其添加到可执行文件中应该可以工作。实际上有一整页 documentation 为了这个。很惊讶你没找到。

    无论如何

    文件说: pyinstaller --additional-hooks-dir=. myscript.py .

    我想大概是这样 pyinstaller --additional-hooks-dir=C:\pathtofolder myscript.py 应该在理论上可行。还需要测试。告诉我们它是如何进行的,是什么让kinks为你工作的。

    最后,如果你想成为一个时髦的尝试集成cython的速度和模糊。值得注意的是,cython并不像pyinstaller看起来那么友好。我还没有成功地使用它。