让Python忽略.pyc文件
有没有办法让Python忽略所有的.pyc文件,直接解释所有代码(包括导入的模块)呢?我在谷歌上找了找,没有找到答案,所以我猜可能不行,但还是想问问,万一有呢。
(我为什么想这么做呢?我有一大堆Python脚本,它们会在几百台电脑上反复运行。这些脚本存放在一个共享的NFS文件系统上。奇怪的是,经过几小时的多次运行后,它们有时会突然崩溃,报错说无法导入某个模块。强制重新生成.pyc文件就能解决这个问题。我当然想修复根本原因,但在这之前,我们也需要系统继续运行,所以如果能忽略.pyc文件,似乎是个合理的解决办法。)
附言:我用的是Python 2.5,所以不能使用-B选项。
6 个回答
如果你正在使用 Python 2.6 或更高版本,并且有类似的问题,最简单的解决办法是:
- 删除所有的 .pyc 文件
- 在运行你的 Python 解释器时加上
-B
这个选项,这样它就不会生成 .pyc 文件了。
根据文档说明:
-B 如果使用这个选项,Python 在导入源模块时就不会尝试写入 .pyc 或 .pyo 文件。你也可以看看 PYTHONDONTWRITEBYTECODE。
这个功能在 2.6 版本中新增。
如果你不能删除所有的 .pyc 文件,你可以:
1) 在运行你的 Python 解释器时加上 -B -O
这两个选项。
这样会告诉 Python 去找 .pyo 文件作为字节码,而不是 .pyc 文件(-O
),同时也告诉 Python 不要生成任何字节码文件(-B
)。
这两个选项结合使用的效果是,假设你之前没有用过它们,Python 就不会生成任何字节码文件,也不会去找之前运行时生成的字节码文件。
根据文档说明:
-B 如果使用这个选项,Python 在导入源模块时就不会尝试写入 .pyc 或 .pyo 文件。你也可以看看 PYTHONDONTWRITEBYTECODE。
这个功能在 2.6 版本中新增。
-O 开启基本的优化。这会把编译(字节码)文件的扩展名从 .pyc 改为 .pyo。你也可以看看 PYTHONOPTIMIZE。
这可能不是你想要的答案,但如果你删除现有的 .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
你可以使用标准的Python库里的imp模块来重新实现__builtins__.__import__
这个函数。这个函数是当你使用import
或者from
语句时被调用的。特别是,imp.load_module这个函数可以用来加载一个.py
文件,即使对应的.pyc
文件已经存在。一定要仔细阅读我提到的页面上的所有文档,还有import的文档,因为这个工作有点复杂。文档里建议使用导入钩子(import hooks),但对于这个特定的任务,我觉得那样可能会更难。
顺便提一下,你遇到的问题可能是因为不同的电脑在同时尝试写.pyc
文件时出现了竞争条件——NFS锁定的稳定性一直都不太好;-)。只要你使用的每个Python编译器版本相同(如果不相同,那你就麻烦大了;-),我建议把所有的.py
文件预编译成.pyc
,然后把它们的目录设置为只读;这样做似乎是最简单的方法(而不是去修改__import__
),即使你出于某种原因无法预编译。