让Python忽略.pyc文件
有没有办法让 Python 忽略任何存在的 .pyc 文件并始终直接解释所有代码(包括导入的模块)?谷歌还没有找到任何答案,所以我怀疑没有,但为了以防万一,似乎值得一问。
(为什么我要这样做?我有一个大型 Python 脚本管道,这些脚本在数百台计算机的集群上重复运行。Python 脚本本身位于共享 NFS 文件系统上。不知何故,很少在运行数百台计算机后在几个小时内,它们会突然开始崩溃,并出现无法导入模块的错误,当然,我想修复根本原因。同时我们还需要系统继续运行,因此如果可能的话,忽略 .pyc 文件似乎是一个合理的解决方法)。
PS我使用的是Python 2.5,所以我不能使用-B。
Is there a way to make Python ignore any .pyc files that are present and always interpret all the code (including imported modules) directly? Google hasn't turned up any answers, so I suspect not, but it seemed worth asking just in case.
(Why do I want to do this? I have a large pipeline of Python scripts which are run repeatedly over a cluster of a couple hundred computers. The Python scripts themselves live on a shared NFS filesystem. Somehow, rarely, after having been run hundreds of times over several hours, they will suddenly start crashing with an error about not being able to import a module. Forcing the regeneration of the .pyc file fixes the problem. I want, of course, to fix the underlying causes, but in the meantime we also need the system to continue running, so it seems like ignoring the .pyc files if possible would be a reasonable workaround).
P.S. I'm using Python 2.5, so I can't use -B.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用标准Python库的imp模块来重新实现
__builtins__.__import__
,它是由import
和from<调用的钩子函数/代码> 声明。特别是, imp.load_module 函数可用于加载 < code>.py
即使存在相应的.pyc
也是如此。请务必仔细研究我指向的页面中的所有文档,以及 导入,因为这是一项微妙的工作。文档本身建议使用导入钩子(根据 PEP 302),但对于这个特定的任务,我怀疑这会更加困难。顺便说一句,您观察到的问题的可能原因包括尝试同时写入
.pyc
文件的不同计算机之间的竞争条件 - NFS 锁定是出了名的不稳定,而且一直如此;-)。只要您使用的每个 Python 编译器都处于同一版本(如果不是,您无论如何都会遇到大麻烦;-),我宁愿将所有这些.py
文件预编译为 < code>.pyc 并将其目录设为只读;无论如何,后者似乎是最简单的方法(而不是破解__import__
),即使由于某种原因您无法预编译。You could use the standard Python library's imp module to reimplement
__builtins__.__import__
, which is the hook function called byimport
andfrom
statement. In particular, the imp.load_module function can be used to load a.py
even when the corresponding.pyc
is present. Be sure to study carefully all the docs in the page I've pointed to, plus those for import, as it's kind of a delicate job. The docs themselves suggest using import hooks instead (per PEP 302) but for this particular task I suspect that would be even harder.BTW, likely causes for your observed problems include race conditions between different computers trying to write
.pyc
files at the same time -- NFS locking is notoriously flaky and has always been;-). As long as every Python compiler you're using is at the same version (if not, you're in big trouble anyway;-), I'd rather precompile all of those.py
files into.pyc
and make their directories read-only; the latter seems the simplest approach anyway (rather than hacking__import__
), even if for some reason you can't precompile.这并不完全是您所要求的,但会删除现有的 .pyc 文件,然后不再为您创建任何工作吗?在这种情况下,您可以使用 -B 选项:
It's not exactly what you asked for, but would removing the existing .pyc files and then not creating any more work for you? In that case, you could use the -B option:
如果有人使用 python 2.6 或更高版本遇到同样的问题,最简单的做法是:
-B
选项运行所有 python 解释器,这样它们就不会生成.pyc 文件。来自文档:
如果您无法删除所有 .pycs,那么您可以:
1) 使用
-B -O
选项运行所有 python 解释器。这将告诉 python 查找 .pyo 文件而不是 .pyc 文件(
-O
)来查找字节码,并告诉 python 不要生成任何字节码文件(-B
)。假设您以前没有使用过这两个选项,那么 Python 将不会生成任何字节码文件,也不会查找由旧运行生成的字节码文件。
来自文档:
In case anyone is using python 2.6 or above with the same question, the simplest thing to do is:
-B
option, so they won't generate .pyc files.From the docs:
If you can't delete all the .pycs, then you could:
1) Run all your python interpreters with the
-B -O
options.This will tell python to look for .pyo files for bytecode instead of .pyc files (
-O
) and tell python not to generate any bytecode files (-B
).The combination of the two options, assuming you haven't used them before, is that Python won't generate any bytecode files and won't look for bytecode files that would have been generated by older runs.
From the docs:
也许您可以通过例如安排作业定期关闭脚本并删除 .pyc 文件来解决此问题。
Perhaps you could work around this by, for example, scheduling a job to periodically shut down the scripts and delete the .pyc files.
好吧,如果您从文件加载代码,我认为 Python 不会直接解释代码。即使使用交互式 shell,Python 也会将导入的模块编译为 .pyc。
也就是说,您可以编写一个 shell 脚本,在启动脚本之前删除所有 .pyc 文件。这肯定会迫使每次执行之前进行全面重建。
Well, I don't think Python ever interprets code directly if you're loading the code from a file. Even when using the interactive shell, Python will compile the imported module into a .pyc.
That said, you could write a shell script to go ahead and delete all the .pyc files before launching your scripts. That would certainly force a full rebuild before every execution.
您可能会发现 PEP 3147 - PYC 存储库目录 非常感兴趣Python 3.2 及以上版本。
You may find PEP 3147 - PYC Repository Directories to be of great interest from Python 3.2 onwards.