32

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

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

到:

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

我想要这个,因为我觉得它会更有条理。感谢你给与我的帮助。

4

10 回答 10

20

更新:

在 Python 3.8-X pycache_prefix=PATH中,命令行选项允许将.pyc文件写入以给定目录为根的并行树,而不是代码树。请参阅$PYTHONPYCACHEPREFIXenvvar学分:@RobertT' 答案

缓存的位置在sys.pycache_prefix(表示[自 Python 3.2] 子目录None中的默认位置) 中报告。__pycache__

可以设置关闭缓存编译后的 Python 字节码,-B然后 Python 不会尝试.pyc在导入源模块时写入文件。请参阅$PYTHONDONTWRITEBYTECODEenvvar学分:@Maleev 的回答


旧 [Python 2] 答案:

PEP 304:控制字节码文件的生成。它的状态是Withdrawn和相应的补丁被拒绝。因此,可能没有直接的方法来做到这一点。

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

于 2009-01-23T05:26:17.913 回答
18

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

经过多年的磨难,2009年的最后几天,新的挑战者崛起。巴里华沙召唤了PEP 3147并派它进行战斗,挥舞着简单的武器,技巧娴熟。PEP 粉碎了杂乱无章的 PYC 文件,让警惕的 Unladen Swallow 和 CPython 解释器保持沉默,每个人都试图争辩说它的 PYC 文件应该是胜利的,并让 Python 可以轻松地休息,它的死鬼偶尔会在深夜运行。PEP 3147 被独裁者认为值得,并在 3.2 的日子里被封为官方角色。

从 3.2 开始,Python 将模块的 PYC 文件存储在__pycache__模块的目录下。每个 PYC 文件都包含解释器的名称和版本,例如__pycache__/foo.cpython-33.pyc. 你可能也有一个__pycache__/foo.cpython-32.pyc由早期版本的 Python 编译的。正确的魔法发生了:如果与源代码不同步,则使用正确的并重新编译。在运行时,查看模块的mymodule.__cached__pyc 文件名并使用imp.get_tag(). 有关更多信息,请参阅新增功能部分

TL;DR - 仅适用于 Python 3.2 及更高版本。糟糕的黑客替代了之前的版本。

于 2013-05-10T06:30:04.247 回答
7

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

于 2018-11-19T02:40:41.893 回答
4

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

python -B file_that_imports_others.py

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

于 2010-06-06T21:19:39.167 回答
3

我同意,将您的代码作为鸡蛋分发是保持其井井有条的好方法。有什么比包含您需要的所有代码和元数据的单个文件更有条理的了。改变字节码编译器的工作方式只会造成混乱。

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

于 2009-01-23T13:23:25.050 回答
3

我不同意。原因是错误的,或者至少没有很好地阐述;但方向是有效的。能够将源代码与编译对象分离是有充分理由的。以下是其中的一些(我曾在某个时候遇到过所有这些):

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

所有这些问题都有解决方法,但它们大多是解决方法而不是解决方案。在大多数情况下,正确的解决方案是让软件接受用于存储和查找这些过渡文件的替代位置。

于 2010-01-10T04:49:45.223 回答
2

由于 Python 3.2 已经实现PEP 3147:这意味着所有 .pyc 文件都在__ pycache __目录中生成(每个目录都有一个__ pycache __目录,每个目录都有 Python 文件,它将保存 .pyc 文件源代码中使用的每个 Python 版本)

于 2013-04-02T23:54:50.850 回答
1

正在进行 pep 可以将字节码构建到魔法目录

基本上所有的python文件都会被编译到目录__pythoncache__中。

于 2012-08-07T15:40:23.427 回答
1

对于 Python 3.8 或更高版本:

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

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

于 2019-04-30T16:58:12.320 回答
-2

“我觉得它会更有条理” 为什么?如何?你想达到什么目的?

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

它们不是必需的;他们很有帮助。为什么要关闭该帮助?

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

于 2009-01-23T11:20:21.163 回答