【问题标题】:Python *.py, *.pyo, *.pyc: Which can be eliminated for an Embedded System?Python *.py、*.pyo、*.pyc:嵌入式系统可以消除哪些?
【发布时间】:2009-05-12 00:18:59
【问题描述】:

为了充分利用我目前正在使用的嵌入式系统中可用的有限文件系统存储空间,我想消除任何可以合理删除而不会显着影响功能或性能的文件。 Python 库中的 *​​.py、*.pyo 和 *.pyc 文件占了相当大的空间,我想知道这些选项中的哪一个对于在小型嵌入式系统中安装 Python 2.6 最合理:

  1. 保留 *.py,消除 *.pyc 和 *.pyo(保持调试能力,性能受损?)
  2. 保留*.py 和*.pyc,消除*.pyo(优化真的有什么用吗?)
  3. 保留 *.pyc,消除 *.pyo 和 *.py(这样行吗?)
  4. 保留 *.py、*.pyc 和 *.pyo(都需要?)

【问题讨论】:

  • 我记得,.pyc 文件是在第一次运行 .py 文件时自动生成的。
  • 第一次导入.py文件时会自动生成.pyc文件

标签: python embedded


【解决方案1】:

http://www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html

当使用 -O 标志调用 Python 解释器时,会生成优化代码并将其存储在“.pyo”文件中。优化器目前没有多大帮助;它只删除断言语句。

将两个 -O 标志传递给 Python 解释器 (-OO) 将导致字节码编译器执行优化,在极少数情况下可能会导致程序出现故障。目前仅从字节码中删除 doc 字符串,从而生成更紧凑的“.pyo”文件。

我对你的建议?

如果您不需要 assert 语句和 __doc__ 字符串,请使用 -OO 仅编译 .pyo 文件。

否则,仅使用 .pyc

编辑

我注意到您只提到了 Python 库。如果您只需要部分功能,可以删除大部分 python 库。

我还建议您查看tinypy,它是 Python 的一个大子集,大约 64kb。

【讨论】:

  • Tinypy 看起来很有趣,虽然它对于我的需要可能有点了。
  • 应该注意的是,pycs 并不总是能很好地转移到其他版本的 python。这对 OP 来说可能不是问题,但如果他有足够的空间,那就不用担心了。
  • @Jason,Python 字节码没有规范。因此 pycs 和 pyos 可能恰好在版本之间不兼容。
  • @Unknown:请运行优化和非优化的python,并执行“导入类型”。然后做(假设Linux):'cd /usr/lib/python2.5; ls -l types.py*; grep -F assert types.py' 并解释 pyc 和 pyo 文件之间的大小差异。提前致谢。
  • @ΤZΩΤZΙΟΥ。我运行了 python 2.6.2 并且 pyc 和 pyo 文件的大小完全相同。 types.py 文件没有断言也没有非模块文档字符串。
【解决方案2】:

3 号应该并且将会起作用。您不需要 .pyo 或 .py 文件即可使用编译后的 Python 代码。

【讨论】:

    【解决方案3】:

    我建议只保留 .py 文件。启动时间的差异不是很大,并且有源代码是一个优势,因为它可以在不同的 python 版本下运行而没有任何问题。

    从 python 2.6 开始,将 sys.dont_write_bytecode 设置为 True 将完全禁止编译 .pyc 和 .pyo 文件,因此如果您有 2.6 可用,您可能希望使用该选项。

    【讨论】:

      【解决方案4】:

      以下是我在日常工作中最小化主线 Python 2.7 的磁盘需求的方法:

      1) 从标准库中删除您不需要的包。以下为保守名单:

      bsddb/test ctypes/test distutils/tests email/test idlelib lib-tk
      lib2to3 pydoc.py tabnanny.py test unittest
      

      请注意,某些 Python 代码可能具有令人惊讶的依赖关系;例如setuptools 需要 unittest 才能运行。

      2) 预编译所有 Python 代码,使用 -OO 去除断言和文档字符串。

      find -name '*.py' | python -OO -m py_compile -
      

      注意Python默认不查看.pyo文件;您还必须使用选项或环境变量在运行时明确要求优化。通过以下方式之一运行脚本:

      python -OO -m mylib.myscript
      PYTHONOPTIMIZE=2 python -m mylib.myscript
      

      3) 删除.py 源代码文件(除非您需要将它们作为脚本运行)和.pyc 未优化文件。

      find '(' -name '*.py' -or -name '*.pyc' ')' -and -not -executable -execdir rm '{}' ';'
      

      4) 压缩 Python 库文件。 Python 可以从 zip 文件中加载模块。 zip 文件中的路径必须与包层次结构匹配;因此,您应该在压缩之前将site-packages.egg 目录合并到主库目录中。 (或者您可以在 Python 路径中添加多个 zip 文件。)

      在 Linux 上,Python 的默认路径已经包含 /usr/lib/python27.zip,因此只需将 zip 文件放到那里即可开始使用。

      os.pyo 保留为普通(非压缩)文件,因为 Python 会将此作为完整性检查。如果将其移动到 zip 文件中,每次 Python 调用都会收到警告(尽管一切仍然有效)。或者您可以在此处留下一个空的os.py 文件,然后将真正的文件放入 zip 文件中。

      最后的笔记:

      • 以这种方式,Python 可容纳 7 MB 的磁盘空间。可以做更多的事情来减小大小,但 7 MB 对于我的目的来说已经足够小了。 :)
      • Python 字节码在不同版本之间不兼容,但谁在乎何时是您进行编译而您控制 Python 版本?
      • .pyo zip 文件中的文件在所有情况下都应该是性能上的胜利,除非磁盘非常快并且处理器/RAM 非常慢。无论哪种方式,Python 都是从内存中执行的,而不是磁盘格式,因此它只会影响加载时的性能。虽然剥离文档字符串可以节省相当多的内存。
      • 请注意.pyo 文件不包含assert 语句。
      • .pyo 文件保留函数名称和行号,因此可调试性不会降低:您仍然可以获得很好的回溯,您只需手动查找源代码中的行号,无论如何您都必须这样做。
      • 如果您想在运行时“破解”文件,只需将其放在当前工作目录中即可。它优先于库 zip 文件。

      【讨论】:

        【解决方案5】:

        最终归结为您实际上只需要三个选项之一,但最好的选择是使用 .pys 和 .pyos 或 .pycs。

        以下是我对每个选项的看法:

        1. 如果将 .pys 放入 zip 文件中,您将看不到 pycs 或 pyos 已构建。还应该指出的是,性能差异仅在于启动时间,即使那样,根据我的经验也不是太大(尽管您的里程可能会有所不同)。另请注意,有一种方法可以防止解释器输出 .pycs,正如Algorias 指出的那样。
        2. 我认为这是一个理想的选择(无论是那个还是 .pys 和 .pyos),因为您可以获得性能、可调试性和可靠性的最佳组合。不过,您不一定需要源文件和编译文件。
        3. 如果您真的空间有限并且需要性能,这将起作用。如果可能的话,我建议你保留 .pys。编译的二进制文件(.pycs 或 .pyos)并不总是转移到不同版本的 python。
        4. 除非您计划有时在优化模式下运行,有时在非优化模式下运行,否则您是否需要全部三个是值得怀疑的。

        在空间方面,如果将 .py 文件放在 zip 文件中,与 .pycs 和 .pyos 相比,我的(非常有趣的)经验是压缩效果最好。如果您计划压缩文件,.pyos 不会在纯粹空间方面获得很多,因为文档字符串往往压缩得相当好,并且断言不会占用那么多空间。

        【讨论】:

        • 他使用的是嵌入式系统,所以如果你在 zip 文件中使用 .py,他将有额外的在内存中解压缩的负担(他的内存可能更少)。
        • 你可能是对的。我主要是试图指出每种方法的优缺点,但没有推荐“最佳”方法,因为我不知道 OP 需要什么的具体细节。
        猜你喜欢
        • 2011-06-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        • 2022-10-23
        • 2015-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多