简体   繁体   English

Python 2.5 .pyc文件与Python 2.6 .pyc文件兼容吗?

[英]Are Python 2.5 .pyc files compatible with Python 2.6 .pyc files?

A while ago I had to upgrade some servers from Python 2.4 to Python 2.5. 不久前,我不得不将一些服务器从Python 2.4升级到Python 2.5。 I found that .pyc files created under Python 2.4 would crash when Python 2.5 tried to run them. 我发现当Python 2.5尝试运行它们时,在Python 2.4下创建的.pyc文件将崩溃。

Will this happen again when I upgrade from 2.5 to 2.6? 从2.5升级到2.6会再次发生吗?

EDIT: Here is a bit more detail 编辑:这是更多细节

I have a fileserver that contains the python code. 我有一个包含python代码的文件服务器。 This is accessed by both Ubuntu and Windows servers to run the python code. Ubuntu和Windows服务器均可访问此文件以运行python代码。 When they run the code they produce .pyc files on the fileserver. 当他们运行代码时,它们在文件服务器上生成.pyc文件。

I found that when I upgraded one of the server machines from Python 2.4 to 2.5 I had problems with .pyc files. 我发现,当我将其中一台服务器计算机从Python 2.4升级到2.5时,.pyc文件出现问题。 I'm now not sure whether it was a machine running 2.5 that tried to run 2.4 bytecode or whether it was a 2.4 machine trying to run 2.5 bytecode, but if I deleted the bytecode all went well until the next bytecode clash. 我现在不确定是尝试运行2.4字节码的是运行2.5的机器还是尝试运行2.5字节码的是2.4机器,但是如果我删除了字节码,一切都将顺利进行直到下一个字节码发生冲突。

I upgraded all of the machines to 2.5 and the problem went away. 我将所有机器升级到2.5,问题消失了。

In general, .pyc files are specific to one Python version (although portable across different machine architectures, as long as they're running the same version); 通常, .pyc文件特定于一个Python版本(尽管它们运行相同的版本,但可以在不同的计算机体系结构中移植)。 the files carry the information about the relevant Python version in their headers -- so, if you leave the corresponding .py files next to the .pyc ones, the .pyc will be rebuilt every time a different Python version is used to import those modules. 该文件携带的有关Python版本在他们的头信息-所以,如果你离开相应.py旁边的文件.pyc偏多, .pyc将被重建的每一个不同的Python版本用于导入这些模块时间。 "Trying to run" wrong-version .pyc files is something I never heard about. 我从未听说过“尝试运行”错误版本的.pyc文件。 What architectures were involved? 涉及什么架构? Were the .py files around as they should be? .py文件是否应该存在?

Edit : as the OP clarified that the crashes came when he was running both Python 2.4 and Python 2.5 programs on the same .py files (from two different servers, sharing a network drive), the explanation of the crashes becomes easy. 编辑 :正如OP澄清的那样,当他在同一个.py文件(来自两个不同的服务器,共享一个网络驱动器)上同时运行Python 2.4 Python 2.5程序时,崩溃是发生的,崩溃的说明变得很容易。 The .py files were all the time being recompiled -- by the 2.4 Python when the 2.5 had been the one running them most recently, and vice versa -- and therefore the .pyc files were frantically busy getting rewritten all the time. .py文件一直都在重新编译-2.4版本的Python以前一直在运行2.5版本,反之亦然-因此, .pyc文件一直忙于重写。 Proper file locking on network drives (especially but not exclusively across different operating systems) is notoriously hard to achieve. 众所周知,很难在网络驱动器上正确锁定文件(尤其是但并非仅在不同操作系统上)。 So the following must have happened (the roles could be switched): the 2.4 server had just determined that a .pyc file was fine for it and started reading it; 因此,必须发生以下情况(可以切换角色):2.4服务器刚刚确定一个.pyc文件适合它并开始读取它; before it could finish reading, the 2.5 server (having previously determined that the module needed to be recompiled) wrote over it; 2.5服务器(之前已确定需要重新编译模块)在其完成读取之前将其覆盖; so the 2.4 server ended up with a memory buffer that had (say) the first 4K bytes from the 2.4 version and the next 4K bytes from the 2.5 version. 因此2.4服务器最终以一个内存缓冲区结束,该缓冲区具有(例如)2.4版本的前4K字节和2.5版本的后4K字节。 When it then used that mangled buffer, unsurprisingly... crash !!! 毫无疑问,当它使用该损坏的缓冲区时, 崩溃了 !!!

This can be a real problem if you ever find yourself continuously trying to run a single set of .py files from two or more different versions of Python (even on the same server, without the added complications of network drives). 如果您发现自己不断尝试从两个或多个不同版本的Python(即使在同一台服务器上,没有网络驱动器的复杂性)运行一组.py文件,这可能是一个真正的问题。 The "proper" solution would be something like virtualenv . “适当的”解决方案将类似于virtualenv The (simple, but dirty-ish) hack we adopted at work (many years ago, but it's still in production...!) is to patch each version of Python to produce and use a different extension for its compiled bytecode files: .pyc (or .pyo ) for Python 1.5.2 (which was the most stable "system" version back when we started doing this kludge to newer versions), .pyc-2.0 for 2.0, .pyc-2.2 for 2.2, and so forth (or equivalent .pyo-XY of course). 我们在工作中采用的(简单但肮脏的)hack(很多年前,但仍在生产中!!)是修补每个版本的Python来产生并为其编译的字节码文件使用不同的扩展名: .pyc (或.pyo )为Python 1.5.2 (这是最稳定的“系统”版本,回来时,我们开始做这个杂牌到更新的版本), .pyc-2.0 2.0, .pyc-2.2 2.2,等等(或等效的.pyo-XY )。 I hear this is soon going away at long last (thanks Thomas!-), but it did tide us semi-decently over this ticklish problem for many, many years. 我听说这个问题很快就会消失了(谢谢托马斯!!),但是它确实使我们在很多年以来一直困扰着这个棘手的问题。

A much simpler solution is to keep a single version of Python around, if that's feasible for your system; 一个更简单的解决方案是,如果对您的系统可行,则保留一个Python版本。 if your system has any complications that make it unfeasible to have a single Python version (as ours did, and does), then these days I'd heartily recommend virtualenv , which I've already mentioned. 如果您的系统有任何复杂性,使其无法拥有一个单独的Python版本(就像我们所做的那样),那么这些天我会衷心推荐virtualenv ,我已经提到过。


With the adoption of PEP 3147 in Python 3.2, pyc files for different Python versions are distinguished automatically by filename. 随着Python 3.2中PPE 3147的采用,不同Python版本的pyc文件将通过文件名自动区分。 This should solve most problems with different Python versions overwriting each other's pyc files. 使用不同的Python版本覆盖彼此的pyc文件,这应该可以解决大多数问题。

If you have the source code then it will recompile it for you. 如果您拥有源代码,那么它将为您重新编译。 So in general you are okay. 所以总的来说你还好。

But, this could be bad for you if users with difference versions of Python run from a central installation directory. 但是,如果使用不同版本的Python的用户从中央安装目录运行,这可能对您不利。

It could also be bad if you just have the pyc files. 如果您只有pyc文件,则可能也很糟糕。 I just ran a quick test for you. 我只是为您进行了快速测试。 I created two .pyc files. 我创建了两个.pyc文件。 One in 2.5 and one in 2.6. 2.5分之一,2.6分之一。 The 2.5 won't run in 2.6 and the 2.6 won't run in 2.5. 2.5不能在2.6中运行,而2.6不能在2.5中运行。 Both throw "ImportError: Bad magic number in .." error, which makes sense because the magic number has changed from 2.5 to 2.6. 两者都引发“ ImportError:错误的魔术数字..”错误,这是有道理的,因为魔术数字已从2.5更改为2.6。

If you want to determine this ahead of time you can get the magic number of your Python as follows: 如果您想提前确定,可以按如下所示获取Python的幻数:

$ python -V
Python 2.6.2
# python
>>> import imp
>>> imp.get_magic().encode('hex')
'd1f20d0a'

To get the magic number for a pyc file you can do the following: 要获取pyc文件的幻数,您可以执行以下操作:

>>> f = open('test25.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'b3f20d0a'
>>> f = open('test26.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'd1f20d0a'

The Python version that creates the file is stored in the .pyc file itself. 创建该文件的Python版本存储在.pyc文件本身中。 Usually this means that the .pyc is replaced by one with the correct Python version 通常,这意味着.pyc被正确的Python版本替换为一个

some reasons this might not happen 某些原因可能不会发生
- permissions -权限
- .py file is not available -.py文件不可用

In the case of permission problem, Python will just use the .py and ignore the .pyc (at a cost to performance) 在权限问题的情况下,Python只会使用.py而忽略.pyc(以性能为代价)

I think it is ok between minor versions though, eg a Python2.6.2 .pyc should work with Python2.6.4 我认为在次要版本之间还可以,例如Python2.6.2 .pyc应该与Python2.6.4一起使用

Here is an excerpt from /usr/share/file/magic 这是/ usr / share / file / magic的摘录

# python:  file(1) magic for python
0   string      """ a python script text executable
0   belong      0x994e0d0a  python 1.5/1.6 byte-compiled
0   belong      0x87c60d0a  python 2.0 byte-compiled
0   belong      0x2aeb0d0a  python 2.1 byte-compiled
0   belong      0x2ded0d0a  python 2.2 byte-compiled
0   belong      0x3bf20d0a  python 2.3 byte-compiled
0   belong      0x6df20d0a  python 2.4 byte-compiled
0   belong      0xb3f20d0a  python 2.5 byte-compiled
0   belong      0xd1f20d0a  python 2.6 byte-compiled

So you can see that the correct Python version is indicated by the first 4 bytes of the .pyc file 因此,您可以看到.pyc文件的前4个字节指示了正确的Python版本

有关此问题的建议修补程序,请参见http://www.python.org/dev/peps/pep-3149/ (希望在Python 3.2中可用)

You will certainly need to recompile the bytecode files for them to be of any use. 当然,您将需要重新编译字节码文件才能使用它们。 The bytecode magic number has changed over every major version of Python(*). 字节码幻数在Python(*)的每个主要版本中均已更改。

However, having non-version-matching bytecode files shouldn't ever crash Python. 但是,拥有非版本匹配的字节码文件永远不会使Python崩溃。 It will generally just ignore any bytecode that doesn't have the correct version number, so there shouldn't be an error, it'll just be slower the first time as it recompiles (or slower every time if the user running the scripts doesn't have write permission to update the bytecode). 通常,它只会忽略任何没有正确版本号的字节码,因此不会出现错误,它在第一次重新编译时会变慢(或者如果运行脚本的用户没有,每次都会变慢)没有更新字节码的写入权限)。

(*: and often during the development phases, plus in earlier versions it sometimes changed over minor versions too. See import.c for a full list of magic numbers and their corresponding Python versions.) (*:通常在开发阶段,而且在早期版本中,有时也会在次要版本上进行更改。请参见import.c以获取幻数及其对应的Python版本的完整列表。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM