Python2.5.pyc文件是否与Python2.6.pyc文件兼容?

Python2.5.pyc文件是否与Python2.6.pyc文件兼容?,python,Python,不久前,我不得不将一些服务器从Python2.4升级到Python2.5。我发现在Python2.4下创建的.pyc文件在Python2.5尝试运行时会崩溃 当我从2.5升级到2.6时,这种情况还会发生吗 编辑:这里有更多的细节 我有一个包含python代码的文件服务器。Ubuntu和Windows服务器都可以访问它来运行python代码。当它们运行代码时,会在文件服务器上生成.pyc文件 我发现,当我将其中一台服务器从Python 2.4升级到2.5时,.pyc文件出现了问题。我现在不确定是运

不久前,我不得不将一些服务器从Python2.4升级到Python2.5。我发现在Python2.4下创建的.pyc文件在Python2.5尝试运行时会崩溃

当我从2.5升级到2.6时,这种情况还会发生吗

编辑:这里有更多的细节

我有一个包含python代码的文件服务器。Ubuntu和Windows服务器都可以访问它来运行python代码。当它们运行代码时,会在文件服务器上生成.pyc文件

我发现,当我将其中一台服务器从Python 2.4升级到2.5时,.pyc文件出现了问题。我现在不确定是运行2.5的机器尝试运行2.4字节码,还是运行2.5字节码的2.4机器,但是如果我删除了字节码,那么在下一次字节码冲突之前一切都很顺利


我将所有机器升级到2.5,问题就消失了。

创建文件的Python版本存储在.pyc文件中。 通常这意味着.pyc被具有正确Python版本的替换

由于某些原因,这种情况可能不会发生
-权限
-.py文件不可用

在权限问题的情况下,Python将只使用.py而忽略.pyc(以性能为代价)

我认为在小版本之间是可以的,例如Python2.6.2。pyc应该与Python2.6.4一起工作

下面是/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

因此,您可以看到,正确的Python版本由.pyc文件的前4个字节指示

您当然需要重新编译字节码文件,以便它们能够发挥任何作用。字节码幻数在Python(*)的每个主要版本中都发生了变化

然而,拥有非版本匹配的字节码文件不会使Python崩溃。它通常只会忽略任何没有正确版本号的字节码,因此不会出现错误,只是在第一次重新编译时会变慢(或者如果运行脚本的用户没有更新字节码的写入权限,则每次都会变慢)


(*:通常在开发阶段,加上在早期版本中,它有时也会在次要版本上进行更改。有关魔法数字及其相应Python版本的完整列表,请参阅。)

通常,
。pyc
文件特定于一个Python版本(尽管可以跨不同的机器体系结构移植,但前提是它们运行的是同一版本);这些文件的标题中包含有关相关Python版本的信息——因此,如果将相应的
.py
文件放在
.pyc
文件旁边,则每次使用不同的Python版本导入这些模块时,
.pyc
都将重新生成。“正在尝试运行”错误版本的
.pyc
文件是我从未听说过的事情。涉及到哪些体系结构?
.py
文件是否按应有的方式存在

编辑:正如OP澄清的那样,当他在相同的
.py
文件(来自两个不同的服务器,共享一个网络驱动器)上运行Python 2.4和Python 2.5程序时发生了崩溃,对崩溃的解释变得很简单。
.py
文件一直在被重新编译——当2.5是最近运行它们的时候,2.4 Python一直在重新编译,反之亦然——因此,
.pyc
文件一直在疯狂地忙着重写。正确的文件锁定在网络驱动器上(尤其是但不完全跨不同的操作系统)是出了名的难以实现的。因此,一定发生了以下情况(角色可以切换):2.4服务器刚刚确定
.pyc
文件适合它,并开始读取它;在完成读取之前,2.5服务器(之前已经确定模块需要重新编译)在其上进行写操作;因此2.4服务器最终得到了一个内存缓冲区,该缓冲区(比如)包含(比如)2.4版本的前4K字节和2.5版本的下一个4K字节。当它随后使用损坏的缓冲区时,毫不奇怪…崩溃了

如果您发现自己一直试图从两个或多个不同版本的Python运行一组
.py
文件(即使在同一台服务器上,也不会增加网络驱动器的复杂性),那么这可能是一个真正的问题。“正确”的解决方案可能类似于我们在工作中采用的(简单但肮脏的)黑客(许多年前,但它仍在生产中…!)是对Python的每个版本进行修补,以便为其编译的字节码文件生成并使用不同的扩展名:
.pyc
(或
.pyo
)for Python
1.5.2
(在我们开始对较新版本进行此修改时,这是最稳定的“系统”版本),2.0版的
.pyc-2.0
,2.2版的
.pyc-2.2
,等等(当然也可以是等效的
.pyo-X.Y
),我听说这很快就要结束了(谢谢托马斯!-),但它确实让我们在这个棘手的问题上度过了许多年

一个简单得多的解决方案是保留Python的单一版本,如果这对您的系统来说是可行的;如果您的系统有任何复杂之处,使得使用单一的Python版本变得不可行(正如我们所做的那样),那么这些天我衷心推荐
virtualenv
,我已经提到过了



随着Python 3.2中的采用,不同Python版本的pyc文件将自动通过文件名进行区分。这将解决不同Python版本相互覆盖pyc文件的大多数问题。

如果您有源代码,它将为您重新编译。因此,一般来说,您是可以的

但是,如果使用不同版本Python的用户从中心安装目录运行,这可能对您不利

如果你只有pyc文件也可能不好。我只是快速运行了一个测试
$ python -V
Python 2.6.2
# python
>>> import imp
>>> imp.get_magic().encode('hex')
'd1f20d0a'
>>> f = open('test25.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'b3f20d0a'
>>> f = open('test26.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'd1f20d0a'