24

有没有办法让 Python 忽略存在的任何 .pyc 文件并始终直接解释所有代码(包括导入的模块)?谷歌没有找到任何答案,所以我怀疑没有,但似乎值得一问,以防万一。

(我为什么要这样做?我有一个庞大的 Python 脚本管道,它们在数百台计算机的集群上重复运行。Python 脚本本身存在于共享的 NFS 文件系统上。不知何故,很少,在运行了数百在几个小时内,他们会突然开始崩溃,出现关于无法导入模块的错误。强制重新生成 .pyc 文件可以解决问题。当然,我想解决根本原因,但是在与此同时,我们还需要系统继续运行,所以如果可能的话,忽略 .pyc 文件似乎是一个合理的解决方法)。

PS我使用的是Python 2.5,所以我不能使用-B。

4

6 回答 6

13

这不完全符合您的要求,但会删除现有的 .pyc 文件,然后不再为您创建任何工作吗?在这种情况下,您可以使用 -B 选项:

>python --help
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
于 2010-08-17T15:14:57.747 回答
13

可以使用标准 Python 库的 imp 模块来重新实现,这是由and语句__builtins__.__import__调用的钩子函数。特别是,imp.load_module函数可用于加载 a即使对应的存在。请务必仔细研究我指出的页面中的所有文档,以及那些用于import的文档,因为这是一项微妙的工作。文档本身建议使用导入钩子(根据 PEP 302),但对于这个特定的任务,我怀疑这会更难。importfrom.py.pyc

顺便说一句,您观察到的问题的可能原因包括尝试同时写入.pyc文件的不同计算机之间的竞争条件——NFS 锁定是出了名的不稳定,而且一直都是;-)。只要您使用的每个 Python 编译器都使用相同的版本(如果不是,那么您无论如何都会遇到大麻烦;-),我宁愿将所有这些.py文件预编译成.pyc并将它们的目录设为只读;无论如何,后者似乎是最简单的方法(而不是 hacking __import__),即使由于某种原因您无法预编译。

于 2010-08-17T15:21:35.487 回答
6

如果有人使用 python 2.6 或更高版本来解决同样的问题,最简单的做法是:

  1. 删除所有 .pyc 文件
  2. 使用该选项运行所有 python 解释器-B,这样它们就不会生成 .pyc 文件。

从文档:

-B 如果给定,Python 不会尝试在导入源模块时写入 .pyc 或 .pyo 文件。另请参阅 PYTHONDONTWRITEBYTECODE。

2.6 版中的新功能。

如果您无法删除所有 .pycs,那么您可以:

1) 使用选项运行所有 python 解释器-B -O

这将告诉 python 为字节码寻找 .pyo 文件而不是 .pyc 文件 ( -O),并告诉 python 不要生成任何字节码文件 ( -B)。

这两个选项的组合,假设您以前没有使用过它们,Python 不会生成任何字节码文件,也不会查找旧运行会生成的字节码文件。

从文档:

-B 如果给定,Python 不会尝试在导入源模块时写入 .pyc 或 .pyo 文件。另请参阅 PYTHONDONTWRITEBYTECODE。

2.6 版中的新功能。

-O 打开基本优化。这会将已编译(字节码)文件的文件扩展名从 .pyc 更改为 .pyo。另请参阅 PYTHONOPTIMIZE。

于 2014-07-23T11:47:42.177 回答
0

好吧,如果您从文件中加载代码,我认为 Python 不会直接解释代码。即使使用交互式 shell,Python 也会将导入的模块编译为 .pyc。

也就是说,您可以编写一个 shell 脚本来继续并在启动脚本之前删除所有 .pyc 文件。这肯定会在每次执行之前强制进行完全重建。

于 2010-08-17T15:25:22.967 回答
0

从 Python 3.2 开始,您可能会发现PEP 3147 - PYC 存储库目录非常有趣。

于 2010-08-18T00:48:05.200 回答
0

也许您可以通过例如安排一个作业来定期关闭脚本并删除 .pyc 文件来解决此问题。

于 2010-08-17T15:14:39.847 回答