什么是错误的幻数错误?


320

什么是python中的“错误魔术数字” ImportError,该如何解决?

我在网上可以找到的唯一东西表明,这是由于编译.py-> .pyc文件,然后尝试将其与错误版本的python一起使用而引起的。但是,就我而言,该文件有时可以很好地导入,而其他时候则不能,并且我不确定为什么。

python在回溯中提供的信息不是特别有用(这就是为什么我在这里询问...的原因),但是在这里它是有帮助的:

Traceback (most recent call last):
  File "run.py", line 7, in <module>
    from Normalization import Normalizer

您能提供发生问题的代码吗?
Evan Fosmark,2009年

您正在使用哪个版本的python?
paxdiablo,

标准化是您的文件之一还是第三方的文件?
paxdiablo,2009年

3
嗯,好吧,我想我一定是在导入一个旧的.pyc文件,该文件是很久以前在移动.py文件时留下的,因此我可以导入新版本,但不能导入旧版本。
诺亚

1
我将旧的.pyc文件删除了,所以没有用,但是我的问题是导入路径-我认为如果我不移动它,python会使用.py文件来重新创建.pyc文件。 (是吗?)
诺亚(Noah

Answers:


400

幻数来自UNIX类型的系统,其中文件的前几个字节包含一个指示文件类型的标记。

Python pyc在创建文件时会将类似的标记放入其文件中。

然后,python解释器会在加载时确保此数字正确。

任何损坏此幻数的东西都会引起您的问题。这包括编辑pyc文件或尝试pyc从解释器以外的其他版本的python(通常更高版本)运行。

如果它们是您的 pyc文件,只需删除它们,然后让解释器重新编译py文件。在UNIX类型的系统上,这可能很简单:

rm *.pyc

要么:

find . -name '*.pyc' -delete

如果不是您自己的py文件,则必须获取文件以进行重新编译,或者需要具有可以pyc使用该特定魔术值运行文件的解释器。

一件事可能导致间歇性。该pyc是造成该问题可能只在一定条件下进口。有时不太可能导入。导入失败时,您应该检查实际的完整堆栈跟踪吗?

顺便说一句,我所有2.5.1(r251:54863) pyc文件的第一个单词是621312.6.1(r261:67517)62161。所有魔幻数字的列表都可以在中找到Python/import.c,为完整起见,在此复制(此处为发布答案时的最新信息,此后可能已更改):

1.5:   20121
1.5.1: 20121
1.5.2: 20121
1.6:   50428
2.0:   50823
2.0.1: 50823
2.1:   60202
2.1.1: 60202
2.1.2: 60202
2.2:   60717
2.3a0: 62011
2.3a0: 62021
2.3a0: 62011
2.4a0: 62041
2.4a3: 62051
2.4b1: 62061
2.5a0: 62071
2.5a0: 62081
2.5a0: 62091
2.5a0: 62092
2.5b3: 62101
2.5b3: 62111
2.5c1: 62121
2.5c2: 62131
2.6a0: 62151
2.6a1: 62161
2.7a0: 62171

2
谢谢-这并不能直接帮助我解决问题,但是无论如何还是很高兴知道答案的!
诺亚

我如何检查哪个pyc文件导致了该问题,我已删除了所有pyc文件,但仍然收到此错误。
sunprophit

也许您现在需要'rm __pycache __ / * pyc',因为pyc文件现在位于该文件夹中。
Arpad Horvath

1
谢谢!这是发生在我身上的错误:ERROR:tornado.general:无法为“ es”加载翻译:[Errno 0]错误的魔术数字:“ / app / locale / es / LC_MESSAGES / django.mo”。实际上,* .mo编译不正确。
ericson.cepeda


60

删除所有.pyc文件将解决“错误的魔术数字”错误。

find . -name "*.pyc" -delete

8
最好使用它find . -name "*.pyc" -delete,因为如果您扩展所有要传递给的文件名,则会遇到空格问题(可能是命令行太长)rm
安德鲁·艾丽特

25
IMO那是一个非常危险的脚本。如果软件包仅附带.pyc文件以保持其源封闭怎么办?糟糕,您刚刚删除了该应用程序。
丹·曼蒂拉

3
最好先运行find . -name "*.pyc" -print,然后再手动删除有问题的文件,和/或在确认您没有做令人遗憾的事情后运行上面的命令。
迈克尔

9
@DanMantyla无论如何,关闭的源程序包都应该删除。

25

*.pyc使用python2 加载python3生成的文件也会导致此错误。


3
这可能是评论,而不是答案。
Kroltan 2014年

2
@Kroltan但这是一个很好的答案,比公认的要好。简洁明了。
安东尼·哈奇金斯

@AntonyHatchkins至少在我看来,这可能是对任何暗示删除.pyc的答案的评论。即使这是一个可能的原因,也没有不同的解决方案,所以这是多余的。随意不同意,只是我的意见。
Kroltan

@Kroltan这里的“如何修复”部分非常明显。原因,至少对我而言,真正有趣的是。我对不同的python 2.x版本进行了很多处理,但从未遇到.pyc版本之间的任何不兼容性。而且此解决方案说这是python3 vs python2问题-可接受的答案中缺少信息。另外,我喜欢简短的答案(可能的话):)
安东尼·哈奇金斯

@AntonyHatchkins,此解决方案很可能说这是py2 / 3问题,但这只是一种可能性,因此,自第一个版本以来
它就

6

将pyc文件放入Windows机器。使用任何十六进制编辑器打开此pyc文件。我使用了免费软件“ HexEdit”。现在读取前两个字节的十六进制值。就我而言,这些是03 f3。

打开calc并将其显示模式转换为Programmer(在XP中为Scientific),以查看十六进制和十进制转换。从单选按钮中选择“十六进制”。首先输入值作为第二个字节,然后输入第一个字节,即f303现在单击“ Dec”(十进制)单选按钮。显示的值是一个对应于python的幻数(又称魔术版本)的值。

因此,考虑先前答复中提供的表

  • 1.5 => 20121 => 4E99,因此文件的第一个字节为99,第二个字节为4e
  • 1.6 => 50428 => C4FC,因此文件的第一个字节为fc,第二个字节为c4

2

如果您使用扩展名.pyc手动命名文件,也会发生“错误的魔术数字”错误


1

使用非常旧的(1.5.2)实现,我遇到了一个奇怪的错误数字魔术错误的案例。我生成了一个.pyo文件,并触发了错误。奇怪的是,通过更改模块名称解决了该问题。令人反感的名称是sms.py。如果我从该模块生成了一个sms.pyo,则结果是错误的幻数错误。当我将名称更改为smst.py时,错误消失了。我来回检查了一下sms.py是否以某种方式干扰了其他任何同名模块,但找不到任何名称冲突。即使这个问题的根源对我来说仍然是莫名其妙,但我还是建议您尝试更改模块名称。


1

这也可能是由于__init__.py目录中缺少文件。假设如果您在django中创建了一个新目录以将单元测试分为多个文件并将它们放置在一个目录中,那么您还必须__init__.py在新创建的测试目录中的所有其他文件旁边创建该文件。否则会出现类似的错误 Traceback (most recent call last): File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python35\Lib\unittest\loader.py",line 153, in loadTestsFromName module = __import__(module_name) ImportError: bad magic number in 'APPNAME.tests': b'\x03\xf3\r\n'


0

这比上面的要有效得多。

find {directory-of-.pyc-files} -name "*.pyc" -print0 | xargs -0 rm -rf

哪里{directory-of-.pyc-files}是包含已编译p​​ython文件的目录。


1
如果您手头有py文件,那么如果没有,您将需要降级python安装。
列昂·费多托夫

1
在某些情况下,这仍然是不安全的。另外,为什么我们在谈论文件时进行递归删除?
Jerome Baum 2012年

1
为什么要使用两个过程?即使发现没有删除,您仍然可以运行find /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana 2012年

1
如果xargs rm直接使用默认的-print final运算符,则'find'命令将不适用于带有空格的文件名。Python不会像这样导入非标识符命名的文件,但是脚本仍然可能导致这种情况中断,并且不会被删除。通常,在find命令上使用额外的-print0(最后为零)(作为'|'管道符号之前的最后一个参数),然后在xargs上使用-0选项(即连字符+零)来理解-总是更安全。当管道找到xargs时,在rm命令之前输出print0。
Breezer

0

在我的情况下,重命名自己的模块后,它不是.pyc旧的二进制.mo翻译文件,因此在此模块文件夹中,我必须运行

find . -name \*.po -execdir sh -c 'msgfmt "$0" -o `basename $0 .po`.mo' '{}' \;

(请先备份并尝试先修复.pyc文件)


0

如果您使用了错误的python27.dll文件(对于Windows),也会发生这种情况,要解决此问题,只需使用确切的相应dll版本重新安装(或解压缩)python。我也有类似的经历。


0

我只是在Fedora26上遇到过同样的问题,由于六位数的错误魔术数,dnf之类的许多工具都被破坏了。由于未知的原因,我有一个/usr/bin/six.pyc文件,带有意外的幻数。删除此文件可解决问题


0

就我而言,我有git clone一个lib,其中包含

#!/usr/bin/env python

尽管python导致Python2.7我的主要代码与python3.6一起运行,但仍导致该*.pyc文件的2.7版本...

我可以说这个错误可能是2.7和3+版本之间混合使用的结果,这就是为什么清理(无论如何都可以认为正在使用)-在这里有帮助...

  • 不要忘记调整那些Python2x代码-> python 3 ...

-1

不要删除它们!!!直到..........

在您的git,svn或copy文件夹中找到有效的版本。

删除它们,然后恢复所有.pyc。

那对我有用。


eyyy为什么我有-1?它确实对我有用,而且我的处境非常糟糕
¬– lauralacarra

2
恢复到以前的版本不是全局解决方案
ZiTAL

4
为什么要提交 *.pyc文件?
Manos Kounelakis

那是通常的错误。当您没有正确配置git忽略文件时。所以我给解决方案,然后您必须订购您的git。
lauralacarra

-1

您将需要在环境中的所有路径中运行此命令。

>>> import sys
>>> sys.path
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/dist-packages', '/source_code/src/python', '/usr/lib/python3/dist-packages']

然后在每个目录中运行命令

find /usr/lib/python3.6/ -name "*.pyc" -delete
find /usr/local/lib/python3.6/dist-packages -name "*.pyc" -delete
# etc...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.