【问题标题】:Compatibility of versions for compiled Python code using modules使用模块编译的 Python 代码的版本兼容性
【发布时间】:2018-04-03 20:16:38
【问题描述】:

假设我编译了一些 python 文件(.py.pyc / .pyo),其中包含使用 NumPy、SciPy、MatPlotLib 等模块的代码。如果我在另一个配置(即客户端)上执行它们,是否需要模块的版本相同?还是我只能在兼容版本的范围内?

【问题讨论】:

    标签: python python-2.7 python-module pyc


    【解决方案1】:

    .pyc.pyo 文件只是缓存的字节码。 Python 的导入机制完全围绕字符串构建,这使得执行导入的代码与它们导入的任何库分离。

    因此,与源代码本身相比,这些文件与它们导入的库的版本无关。如果源代码适用于各种版本的库,那么编译后的字节码也适用。

    您可以随时查看 Python 使用 dis module 生成的字节码。直截了当的import 声明变为:

    >>> import dis
    >>> dis.dis(compile('import numpy as np', '', 'single'))
      1           0 LOAD_CONST               0 (0)
                  2 LOAD_CONST               1 (None)
                  4 IMPORT_NAME              0 (numpy)
                  6 STORE_NAME               1 (np)
                  8 LOAD_CONST               1 (None)
                 10 RETURN_VALUE
    

    IMPORT_NAME opcode 的名称来自附加到代码对象(也存储在缓存中)的 co_names 结构:

    >>> compile('import numpy as np', '', 'single').co_names
    ('numpy', 'np')
    

    numpy 模块包含大部分动态加载的库并不重要;如果您将 name numpy 替换为将要导入的其他内容。模块是在运行时加载的,毕竟不是在编译时加载的。

    【讨论】:

      【解决方案2】:

      即使是编译后的字节码,模块中的名称仍然是字符串。只要模块的接口兼容,代码仍然适用于不同的模块版本。

      【讨论】:

      • 但是,这并没有扩展到更改底层 Python 运行时的版本——不仅 Python 版本嵌入在生成的文件名中,而且文件本身内部还有一个版本兼容性标记(注意:重新措辞,因为我原来的评论是基于误读问题)
      • 哎呀,没关系,我误读了这个问题 - 我认为它也包括更改 Python 版本(这是会触发重新编译需要的部分)
      猜你喜欢
      • 1970-01-01
      • 2022-11-24
      • 2020-11-04
      • 1970-01-01
      • 2022-01-04
      • 2017-02-13
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      相关资源
      最近更新 更多