Was ist der schlechte magische Zahlenfehler?

319

Was ist der ImportError "Bad Magic Number" in Python und wie behebe ich ihn?

Das einzige, was ich online finden kann, ist, dass dies dadurch verursacht wird, dass eine .py -> .pyc-Datei kompiliert und dann versucht wird, sie mit der falschen Python-Version zu verwenden. In meinem Fall scheint die Datei jedoch einige Male gut zu importieren, andere jedoch nicht, und ich bin mir nicht sicher, warum.

Die Informationen, die Python im Traceback bereitstellt, sind nicht besonders hilfreich (weshalb ich hier gefragt habe ...), aber hier ist es für den Fall, dass es hilft:

Traceback (most recent call last):
  File "run.py", line 7, in <module>
    from Normalization import Normalizer
Noah
quelle
Können Sie den Code angeben, in dem das Problem auftritt?
Evan Fosmark
Und welche Python-Version verwenden Sie?
Paxdiablo
Und ist Normalisierung eine Ihrer Dateien oder eine von Drittanbietern?
Paxdiablo
3
Hrm, okay, ich denke, ich muss eine alte .pyc-Datei importiert haben, die vor langer Zeit zurückgelassen wurde, als ich die .py-Datei verschoben habe, und so konnte ich die neue Version importieren, aber nicht die alte.
Noah
1
Ich habe die alte .pyc-Datei gestrichen, daher habe ich sie nicht zur Hand, aber mein Problem waren die Importpfade. Ich denke, Python hätte die .py-Datei verwendet, um die .pyc-Datei neu zu erstellen, wenn ich sie nicht verschoben hätte (Ist das richtig?)
Noah

Antworten:

399

Die magische Zahl stammt von Systemen vom Typ UNIX, bei denen die ersten Bytes einer Datei eine Markierung enthielten, die den Dateityp angibt.

Python fügt seinen pycDateien beim Erstellen einen ähnlichen Marker hinzu .

Dann stellt der Python-Interpreter sicher, dass diese Nummer beim Laden korrekt ist.

Alles, was diese magische Zahl beschädigt, wird Ihr Problem verursachen. Dies umfasst das Bearbeiten der pycDatei oder den Versuch, eine pycvon einer anderen Python-Version (normalerweise später) als Ihr Interpreter auszuführen .

Wenn es sich um Ihre pyc Dateien handelt, löschen Sie sie einfach und lassen Sie den Interpreter die pyDateien neu kompilieren . Auf UNIX-Systemen kann dies so einfach sein wie:

rm *.pyc

oder:

find . -name '*.pyc' -delete

Wenn sie nicht Ihnen gehören, müssen Sie entweder die pyDateien zur Neukompilierung oder einen Interpreter abrufen, der die pycDateien mit diesem bestimmten magischen Wert ausführen kann .

Eine Sache, die die intermittierende Natur verursachen könnte. Das pycProblem kann möglicherweise nur unter bestimmten Bedingungen importiert werden. Es ist höchst unwahrscheinlich, dass es manchmal importiert wird. Sie sollten die tatsächliche vollständige Stapelverfolgung überprüfen, wenn der Import fehlschlägt.

Abgesehen davon ist das erste Wort aller meiner 2.5.1(r251:54863) pycDateien 62131, 2.6.1(r261:67517)ist 62161. Die Liste aller magischen Zahlen finden Sie in Python/import.c, der Vollständigkeit halber hier wiedergegeben (aktuell zum Zeitpunkt der Veröffentlichung der Antwort, möglicherweise seitdem geändert):

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
paxdiablo
quelle
2
Danke - das hat mir nicht direkt geholfen, mein Problem herauszufinden, aber es ist trotzdem schön, die Antwort zu kennen!
Noah
Wie kann ich überprüfen, welche Pyc-Datei das Problem verursacht? Ich habe alle Pyc-Dateien gelöscht, erhalte aber immer noch diesen Fehler.
Sunprophit
Vielleicht brauchen Sie jetzt 'rm __pycache __ / * pyc', weil sich die pyc-Dateien jetzt in diesem Ordner befinden.
Arpad Horvath
1
Vielen Dank! Es passierte mir mit: FEHLER: tornado.general: Übersetzung für 'es' kann nicht geladen werden: [Errno 0] Schlechte magische Zahl: '/app/locale/es/LC_MESSAGES/django.mo'. Tatsächlich wurde die * .mo nicht korrekt kompiliert.
ericson.cepeda
1
Eine ausführlichere Liste finden Sie hier: github.com/google/pytype/blob/master/pytype/pyc/magic.py
Davy
60

Durch das Löschen aller .pyc-Dateien wird der Fehler "Bad Magic Number" behoben.

find . -name "*.pyc" -delete
akarca
quelle
8
Es ist wahrscheinlich besser zu verwenden find . -name "*.pyc" -delete, da Sie Probleme mit Leerzeichen (und möglicherweise mit einer zu langen Befehlszeile) haben, wenn Sie alle Dateinamen erweitern, an die übergeben werden soll rm.
Andrew Aylett
25
IMO, das ist ein ziemlich gefährliches Skript. Was wäre, wenn ein Paket nur mit .pyc-Dateien geliefert würde, um es als Closed Source zu halten? Hoppla, Sie haben gerade die Anwendung gelöscht.
Dan Mantyla
3
Am besten zuerst ausführen find . -name "*.pyc" -printund erst dann entweder die problematischen Dateien manuell löschen und / oder den obigen Befehl ausführen, nachdem Sie überprüft haben, dass Sie nichts Bedauerliches tun.
Michael
9
@DanMantyla Geschlossene Quellpakete verdienen sowieso das Löschen.
Katze
25

Das Laden einer von Python3 generierten *.pycDatei mit Python2 verursacht ebenfalls diesen Fehler.

jtm
quelle
3
Dies könnte ein Kommentar sein, keine Antwort.
Kroltan
2
@Kroltan noch ist es verdammt gut als Antwort, besser als die akzeptierte. Prägnant und auf den Punkt.
Antony Hatchkins
@AntonyHatchkins Zumindest meiner Ansicht nach könnte dies ein Kommentar zu einer der Antworten sein, die auf das Löschen von .pyc hindeuten. Obwohl dies eine mögliche Ursache ist , gibt es keine andere Lösung , daher ist dies redundant. Fühlen Sie sich frei zu widersprechen, nur meine Meinung.
Kroltan
@Kroltan Der Teil "Wie man das behebt" ist hier ziemlich offensichtlich. Die Ursache, das ist wirklich interessant - zumindest für mich - ist. Ich habe viel mit verschiedenen Python 2.x-Versionen herumgespielt und bin nie auf Inkompatibilitäten zwischen .pyc-Versionen gestoßen. Und diese Lösung besagt, dass es sich um ein Problem zwischen Python3 und Python2 handelt - Informationen fehlen in der akzeptierten Antwort. Außerdem liebe ich kurze Antworten (wo möglich) :)
Antony Hatchkins
@AntonyHatchkins, diese Lösung kann durchaus sagen, dass es sich um ein py2 / 3-Problem handelt, aber das ist nur eine Möglichkeit und eine, die in der akzeptierten Antwort (Absatz 4) seit ihrer allerersten Version vorgeschlagen wurde :-)
paxdiablo
6

Bringen Sie die Pyc-Datei zu einem Windows-Computer. Verwenden Sie einen beliebigen Hex-Editor, um diese Pyc-Datei zu öffnen. Ich habe die Freeware 'HexEdit' verwendet. Lesen Sie nun den Hex-Wert der ersten beiden Bytes. In meinem Fall waren dies 03 f3.

Öffnen Sie calc und konvertieren Sie den Anzeigemodus in Programmer (Scientific in XP), um die Hex- und Dezimalkonvertierung anzuzeigen. Wählen Sie "Hex" aus dem Optionsfeld. Geben Sie zuerst Werte als zweites Byte und dann als erstes Byte ein, dh f303. Klicken Sie nun auf das Optionsfeld "Dez" (Dezimal). Der angezeigte Wert entspricht der magischen Zahl, auch bekannt als Python-Version.

In Anbetracht der Tabelle in der vorherigen Antwort

  • 1.5 => 20121 => 4E99, sodass Dateien das erste Byte als 99 und das zweite als 4e haben würden
  • 1.6 => 50428 => C4FC, sodass Dateien das erste Byte als fc und das zweite als c4 haben
Sanjay Chopra
quelle
2

Der Fehler "Bad Magic Number" tritt auch auf, wenn Sie Ihre Datei manuell mit der Erweiterung .pyc benannt haben

Deke
quelle
1

Ich hatte einen seltsamen Fall eines Bad Magic Number-Fehlers mit einer sehr alten (1.5.2) Implementierung. Ich habe eine .pyo-Datei generiert, die den Fehler ausgelöst hat. Seltsamerweise wurde das Problem durch Ändern des Modulnamens gelöst. Der beleidigende Name war sms.py. Wenn ich aus diesem Modul eine sms.pyo generiert habe, war der Fehler "Bad Magic Number" die Folge. Als ich den Namen in smst.py änderte, verschwand der Fehler. Ich habe hin und her überprüft, ob sms.py ein anderes Modul mit demselben Namen irgendwie gestört hat, aber ich konnte keine Namenskollision finden. Obwohl die Ursache dieses Problems für mich weiterhin ein Rätsel war, empfehle ich, eine Änderung des Modulnamens zu versuchen.

Gábor Paller
quelle
1

Dies kann auch an einer fehlenden __init__.pyDatei im Verzeichnis liegen. Angenommen, Sie erstellen in Django ein neues Verzeichnis, um die Komponententests in mehrere Dateien aufzuteilen und in einem Verzeichnis __init__.pyabzulegen. Dann müssen Sie die Datei neben allen anderen Dateien im neu erstellten Testverzeichnis erstellen . Andernfalls kann es zu Fehlern kommen 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'

Shahraiz Ali
quelle
0

Dies ist viel effizienter als oben.

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

Wo {directory-of-.pyc-files}ist das Verzeichnis, das die kompilierten Python-Dateien enthält?

ozgurv
quelle
1
Dies ist der Fall, wenn Sie die py-Dateien zur Hand haben. Andernfalls müssen Sie die Python-Installation herunterstufen.
Leon Fedotov
1
Dies ist für einige Randfälle immer noch unsicher. Warum löschen wir auch rekursiv, wenn es um Dateien geht?
Jerome Baum
1
Warum verwenden Sie zwei Prozesse? Selbst wenn find nicht gelöscht hätte, könnten Sie trotzdem laufenfind /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana
1
Der Befehl 'find' funktioniert nicht sicher für Dateinamen mit Leerzeichen, wenn der Standardoperator -print final direkt von xargs rm verwendet wird. Python importiert keine Dateien mit dem Namen "Nicht-ID" wie diese, aber Skripte können dazu führen, dass dies nicht funktioniert, und sie werden nicht gelöscht. Im Allgemeinen ist es immer sicherer, für den Befehl find (als letzten Parameter vor dem Pipe-Symbol '|') einen zusätzlichen -print0 (am Ende Null) und für xargs (das ist ein Bindestrich + Null) die Option -0 zu verwenden, um das - zu verstehen print0 wird vor dem Befehl rm ausgegeben, wenn find in xargs weitergeleitet wird.
Breezer
0

In meinem Fall waren es .pycnur alte binäre .moÜbersetzungsdateien, nachdem ich mein eigenes Modul umbenannt hatte, also musste ich in diesem Modulordner ausführen

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

(Bitte sichern Sie und versuchen Sie zuerst, die .pycDateien zu reparieren. )

d9k
quelle
0

Dies kann auch passieren, wenn Sie die falsche Datei python27.dll haben (im Fall von Windows). Um dies zu lösen, installieren Sie Python einfach neu (oder extrahieren Sie es) mit der genau entsprechenden DLL-Version. Ich hatte eine ähnliche Erfahrung.

Ibrahim.H
quelle
0

Ich hatte gerade das gleiche Problem mit Fedora26, bei dem viele Tools wie dnf aufgrund einer schlechten magischen Zahl für sechs defekt waren. Aus einem unbekannten Grund habe ich eine Datei /usr/bin/six.pyc mit der unerwarteten magischen Nummer. Das Löschen dieser Datei behebt das Problem

Zedge
quelle
0

In meinem Fall habe ich git cloneeine Bibliothek, die einen Dolmetscher von hatte

#!/usr/bin/env python

Während dies pythondazu führte, dass Python2.7mein Hauptcode mit Python3.6 ausgeführt wurde, wurde immer noch eine *.pycDatei für die 2.7Version erstellt ...

Ich kann sagen, dass dieser Fehler wahrscheinlich auf eine Mischung aus Versionen 2.7 und 3+ zurückzuführen ist. Aus diesem Grund hilft die Bereinigung (in jeder Hinsicht, die Sie sich vorstellen können, dass Sie sie verwenden) hier ...

  • Vergessen Sie nicht, diesen Python2x-Code anzupassen -> Python 3 ...
Ricky Levi
quelle
-1

Lösche sie nicht !!! Bis..........

Suchen Sie eine Version in Ihrem Git-, SVN- oder Kopierordner, die funktioniert.

Löschen Sie sie und stellen Sie dann alle .pyc wieder her.

Das ist Arbeit für mich.

lauralacarra
quelle
eyyy warum habe ich -1? es funktioniert wirklich für mich und ich war in einer wirklich schlechten Situation
Lauralacarra
2
Zurück zur vorherigen Version ist keine globale Lösung
ZiTAL
4
Warum würden Sie jemals Ihre *.pycDateien festschreiben?
Manos Kounelakis
Das ist der übliche Fehler. Wenn Sie die git-Ignorierdatei nicht richtig konfigurieren. Also gebe ich die Lösung und dann musst du deinen Git bestellen.
Lauralacarra
-1

Sie müssen diesen Befehl in jedem Pfad ausführen, den Sie in Ihrer Umgebung haben.

>>> 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']

Führen Sie dann den Befehl in jedem Verzeichnis hier aus

find /usr/lib/python3.6/ -name "*.pyc" -delete
find /usr/local/lib/python3.6/dist-packages -name "*.pyc" -delete
# etc...
Ahmed
quelle