【问题标题】:pyinstaller: adding dynamically loaded modulespyinstaller:添加动态加载的模块
【发布时间】:2020-08-22 03:18:08
【问题描述】:

我正在尝试使用 Pyinstaller 捆绑一个用 Python3 编写的服务器。部分服务器代码的编写方式是一些模块是这样动态加载的:

mod_files = [f for f in os.listdir(path)]:
for f in mod_files:
   mod = importlib.import_module(mod_name)

如何使用 Pyinstaller 处理这些文件?

【问题讨论】:

    标签: python pyinstaller


    【解决方案1】:

    Pyinstaller(当前为 3.4 版)无法检测像 importlib.import_module() 这样的导入。 Pyinstaller 的documentation 中详细介绍了问题和解决方案,我将其粘贴在下面作为入口点。

    某些 Python 脚本以 PyInstaller 无法检测到的方式导入模块:例如,通过使用带有可变数据的 __import__() 函数、使用 imp.find_module() 或在运行时操纵 sys.path 值。如果你的脚本需要 PyInstaller 不知道的文件,你必须帮助它:

    • 您可以在pyinstaller 命令行上提供其他文件。
    • 您可以在命令行中提供其他导入路径。
    • 您可以编辑 PyInstaller 第一次为您的脚本运行它时编写的 myscript.spec 文件。在规范文件中,您可以告诉 PyInstaller 您的脚本独有的代码模块。 您可以编写通知 PyInstaller 隐藏导入的“挂钩”文件。如果您为其他用户也可能使用的包创建“挂钩”,则可以将挂钩文件贡献给 PyInstaller。

    如果您的程序依赖于对某些数据文件的访问,您可以告诉 PyInstaller 也将它们包含在包中。您可以通过修改规范文件来做到这一点,这是Using Spec Files 中涵盖的高级主题。

    为了在运行时定位包含的文件,您的程序需要能够在运行时以一种无论是否从捆绑包中运行都可以正常工作的方式获知其路径。 Run-time Information 对此进行了介绍。

    【讨论】:

      【解决方案2】:

      我不确定mod_name 的值,但事实证明,私有模块在被 PyInstaller 冻结后可以不能导入。即

      mod = importlib.import_module("module.__somename__")
      

      打包后会导致ModuleNotFoundError,尽管它可能与打包脚本一起工作。

      非私有包应该用 import_module 很好地导入,例如

      mod = importlib.import_module("module.somename")
      

      当然先决条件是确保为任何动态导入模块正确设置--hidden-import,根据文档Listing Hidden Imports

      【讨论】:

        猜你喜欢
        • 2017-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        • 2010-10-31
        • 2021-01-11
        • 2018-06-05
        相关资源
        最近更新 更多