在单独的文件夹中编译python文件的方法?

时间:2009-01-23 05:02:13

标签: python file compiled

是否可以让Python将.pyc个文件保存到sys.path中的单独文件夹位置?

/code
    foo.py
    foo.pyc
    bar.py
    bar.pyc

要:

/code
   foo.py
   bar.py
/code_compiled
   foo.pyc
   bar.pyc

我想这样,因为我觉得它更有条理。谢谢你能给我的任何帮助。

10 个答案:

答案 0 :(得分:17)

PEP 304: Controlling Generation of Bytecode Files。其状态为Withdrawn,相应的patch被拒绝。因此,可能没有直接的方法来做到这一点。

如果您不需要源代码,则可以删除*.py个文件。 *.pyc个文件可以按原样使用,也可以打包在鸡蛋中。

答案 1 :(得分:17)

在2003年的黑暗和古代,PEP 304出现了挑战这个问题。它的补丁被发现缺乏。环境变量平台依赖关系和版本偏差将其撕成碎片,并将其分散在荒地上。

经历了多年的苦难之后,2009年的最后几天,一位新的挑战者崛起。巴里华沙召唤了PEP 3147并派它去战斗,挥舞着一种技巧简单的武器。 PEP粉碎了混乱的PYC文件,让那些试图争辩其PYC文件的Waring Unladen Swallow和CPython解释员沉默,并允许Python轻松休息,其死鬼偶尔在深夜运行。 PEP 3147被独裁者认定是值得的,并且在3.2时被授予官方角色。

从3.2开始,Python将模块的PYC文件存储在模块目录下的__pycache__中。每个PYC文件包含解释器的名称和版本,例如__pycache__/foo.cpython-33.pyc。您可能还有一个早期版本的Python编译的__pycache__/foo.cpython-32.pyc。正确的魔法发生:如果与源代码不同步,则使用正确的魔法并重新编译。在运行时,查看模块的mymodule.__cached__以获取pyc文件名,并使用imp.get_tag()进行解析。有关详细信息,请参阅the What's New section

TL; DR - 只适用于Python 3.2及更高版本。可怜的黑客在此之前替代了版本。

答案 2 :(得分:3)

我同意,将您的代码作为一个鸡蛋分发是保持组织有序的好方法。什么可能比包含您需要的所有代码和元数据的单个文件更有条理。改变字节码编译器的工作方式只会引起混淆。

如果你真的不喜欢这些pyc文件的位置,另一种方法是从只读文件夹运行。由于python无法编写,因此不会生成任何pyc文件。你所采取的打击是每个python文件加载后都必须重新编译,无论你是否更改过它。这意味着你的启动时间会更糟。

答案 3 :(得分:3)

我不同意。原因是错误的,或至少没有很好的表述;但方向是有效的。能够从编译对象中分离源代码是有充分理由的。以下是其中的一些(我曾经遇到过所有这些问题):

  • 嵌入式设备读取ROM,但能够在RAM上使用内存文件系统。
  • multi-os dev环境意味着与我的工作目录共享(使用samba / nfs / whatever)并在多个平台上构建。
  • 商业公司希望只分发pyc以保护IP
  • 使用相同的工作目录轻松运行多个版本的python的测试套件
  • 更容易清理过渡文件(rm -rf $ OBJECT_DIR而不是查找。-name'* .pyc'-exec rm -f {} \;)

所有这些问题都有解决方法,但它们主要是解决方法而不是解决方案。在大多数情况下,适当的解决方案是软件接受另一个位置来存储和查找这些过渡文件。

答案 4 :(得分:3)

如果你愿意为它完全牺牲字节码生成,那就有一个命令行标志:

python -B file_that_imports_others.py

可以放入IDE的构建/运行首选项

答案 5 :(得分:2)

大约十年后,Python 3.8终于支持通过设置环境变量PYTHONPYCACHEPREFIX或使用-X pycache_prefix=PATH参数(官方文档here)将字节码保存在单独的并行文件系统树中。

答案 6 :(得分:1)

正在进行的鼓励enable building bytecode to magic directory

基本上所有python文件都将编译到目录__pythoncache__

答案 7 :(得分:1)

由于Python 3.2已经实现PEP 3147:这意味着所有.pyc文件都是在 __ pycache __ 目录中生成的(会有一个<您拥有Python文件的每个目录的strong> __ pycache __ 目录,并且它将为源上使用的每个Python版本保存.pyc文件)

答案 8 :(得分:0)

对于Python 3.8或更高版本:

PYTHONPYCACHEPREFIX设置(也可以作为-X pycache_prefix使用)将隐式字节码缓存配置为使用单独的文件系统树,而不是每个源中的默认__pycache__子目录目录。

sys.pycache_prefix中报告了缓存的位置(None表示__pycache__子目录中的默认位置)。

答案 9 :(得分:-2)

“我觉得它更有条理”为什么?怎么样?你想要完成什么?

保存编译器输出的目的是在导入模块时节省一点加载时间。为什么要把它变得更复杂?如果您不喜欢.pyc,那么请定期运行“删除所有.pyc”脚本。

它们不是必不可少的;他们很有帮助。为什么关闭那个帮助?

这不是C,C ++或Java,其中结果对象是必不可少的。这只是Python碰巧使用的缓存。我们在Subversion中将它们标记为“忽略”,这样它们就不会意外地结束登记。