Qual è l'errore del numero magico negativo?


320

Che cos'è ImportError "Bad magic number" in Python e come posso risolverlo?

L'unica cosa che posso trovare online suggerisce che ciò è causato dalla compilazione di un file .py -> .pyc e quindi dal tentativo di usarlo con la versione sbagliata di Python. Nel mio caso, tuttavia, il file sembra importare bene alcune volte ma non altre, e non sono sicuro del perché.

Le informazioni fornite da Python nel traceback non sono particolarmente utili (motivo per cui stavo chiedendo qui ...), ma qui è nel caso in cui aiuti:

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

Potresti fornire il codice in cui si verifica il problema?
Evan Fosmark,

E quale versione di Python stai usando?
paxdiablo,

E la normalizzazione è uno dei tuoi file o di terze parti?
paxdiablo,

3
Hm, okay, penso di aver importato un vecchio file .pyc che è stato lasciato indietro molto tempo fa quando ho spostato il file .py e quindi ho potuto importare la nuova versione ma non quella vecchia.
Noah,

1
Ho eliminato il vecchio file .pyc, quindi non ce l'ho a portata di mano, ma il mio problema era con i percorsi di importazione - penso che Python avrebbe usato il file .py per ricreare il file .pyc se non lo avessi spostato (è vero?)
Noah,

Risposte:


401

Il numero magico proviene da sistemi di tipo UNIX in cui i primi byte di un file contenevano un marcatore che indica il tipo di file.

Python inserisce un marcatore simile nei suoi pycfile quando li crea.

Quindi l'interprete python si assicura che questo numero sia corretto durante il caricamento.

Tutto ciò che danneggia questo numero magico causerà il tuo problema. Ciò include la modifica del pycfile o il tentativo di eseguire una pycversione diversa di Python (in genere successiva) rispetto all'interprete.

Se sono i tuoi pyc file, eliminali e lascia che l'interprete ricompili i pyfile. Sui sistemi di tipo UNIX, potrebbe essere qualcosa di semplice come:

rm *.pyc

o:

find . -name '*.pyc' -delete

Se non sono tuoi, dovrai ottenere i pyfile per la ricompilazione o un interprete in grado di eseguire i pycfile con quel particolare valore magico.

Una cosa che potrebbe causare la natura intermittente. Ciò pycche causa il problema può essere importato solo a determinate condizioni. È altamente improbabile che a volte venga importato. Dovresti controllare la traccia dello stack completo quando l'importazione non riesce?

Per inciso, la prima parola di tutti i miei 2.5.1(r251:54863) pycfile è 62131, 2.6.1(r261:67517)è 62161. L'elenco di tutti i numeri magici è disponibile in Python/import.c, riprodotto qui per completezza (attuale come al momento della pubblicazione della risposta, potrebbe essere cambiato da allora):

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
Grazie - questo non mi ha aiutato direttamente a capire il mio problema, ma è comunque bello conoscere la risposta!
Noah,

Come posso verificare quale file pyc causa il problema, ho eliminato tutti i file pyc ma ho ancora riscontrato questo errore.
sunprophit,

Forse hai bisogno di 'rm __pycache __ / * pyc' adesso, perché i file pyc sono ora in quella cartella.
Arpad Horvath,

1
Grazie! Mi stava succedendo con: ERRORE: tornado.general: Impossibile caricare la traduzione per 'es': [Errno 0] Numero magico errato: '/app/locale/es/LC_MESSAGES/django.mo'. In effetti, è stato che * .mo non è stato compilato correttamente.
ericson.cepeda,


60

L'eliminazione di tutti i file .pyc risolverà l'errore "Bad Magic Number".

find . -name "*.pyc" -delete

8
Probabilmente è meglio usarlo find . -name "*.pyc" -delete, poiché avrai problemi con gli spazi (e forse con una riga di comando troppo lunga) se espandi tutti i nomi dei file a cui passare rm.
Andrew Aylett,

25
IMO è una sceneggiatura piuttosto pericolosa. Cosa succederebbe se un pacchetto venisse consegnato con solo file .pyc per tenerlo chiuso? Spiacenti, hai appena eliminato l'applicazione.
Dan Mantyla,

3
Probabilmente è meglio eseguire prima find . -name "*.pyc" -printe solo allora eliminare manualmente i file problematici e / o eseguire il comando sopra, dopo aver verificato che non stai facendo qualcosa di spiacevole.
michael,

9
@DanMantyla I pacchetti sorgente chiusi meritano comunque la cancellazione.
cat

25

Anche il caricamento di un *.pycfile generato da python3 con python2 causa questo errore.


3
Questo potrebbe essere un commento, non una risposta.
Kroltan,

2
@Kroltan eppure è dannatamente buono come risposta, migliore di quello accettato. Conciso e puntuale.
Antony Hatchkins,

@AntonyHatchkins Almeno dal mio punto di vista, questo potrebbe essere un commento su una qualsiasi delle risposte che suggerisce la cancellazione di .pyc. Anche se questa è una possibile causa , non ha una soluzione diversa , quindi è ridondante. Sentiti libero di non essere d'accordo, solo la mia opinione.
Kroltan,

@Kroltan La parte 'come riparare' è abbastanza ovvia qui. La causa, ecco cosa è davvero interessante - almeno per me - è. Ho fatto molti tentativi con diverse versioni di Python 2.x e non ho mai riscontrato incompatibilità tra le versioni .pyc. E questa soluzione afferma che si tratta del problema python3 vs python2 - informazioni mancanti nella risposta accettata. Inoltre adoro le risposte brevi (ove possibile) :)
Antony Hatchkins,

@AntonyHatchkins, questa soluzione potrebbe anche dire che è un problema py2 / 3 ma questa è solo una possibilità e, del resto , una suggerita nella risposta accettata (paragrafo 4) sin dalla sua prima versione :-)
paxdiablo

6

Porta il file pyc su un computer Windows. Utilizzare qualsiasi editor esadecimale per aprire questo file pyc. Ho usato il software gratuito 'HexEdit'. Ora leggi il valore esadecimale dei primi due byte. Nel mio caso, erano 03 f3.

Apri calc e converti la sua modalità di visualizzazione in Programmer (Scientific in XP) per vedere la conversione esadecimale e decimale. Seleziona "Esadecimale" dal pulsante di opzione. Immettere prima i valori come secondo byte e poi il primo byte, ad es. F303 Ora fare clic sul pulsante di opzione "Dec" (Decimale). Il valore visualizzato è uno che corrisponde al numero magico noto anche come versione di Python.

Quindi, considerando la tabella fornita nella risposta precedente

  • 1.5 => 20121 => 4E99 in modo che i file abbiano il primo byte come 99 e il secondo come 4e
  • 1.6 => 50428 => C4FC in modo che i file abbiano il primo byte come fc e il secondo come c4

2

L'errore "Bad magic number" si verifica anche se hai nominato manualmente il tuo file con estensione .pyc


1

Ho avuto uno strano caso di errore Bad Magic Number usando un'implementazione molto vecchia (1.5.2). Ho generato un file .pyo e questo ha scatenato l'errore. Stranamente, il problema è stato risolto modificando il nome del modulo. Il nome offensivo era sms.py. Se avessi generato un smspyo da quel modulo, il risultato sarebbe stato un errore di Bad Magic Number. Quando ho cambiato il nome in smst.py, l'errore è scomparso. Ho controllato avanti e indietro per vedere se sms.py in qualche modo ha interferito con qualsiasi altro modulo con lo stesso nome ma non sono riuscito a trovare alcuna collisione di nomi. Anche se la fonte di questo problema è rimasta un mistero per me, consiglio di provare a cambiare il nome del modulo.


1

Ciò può anche essere dovuto alla mancanza di __init__.pyfile dalla directory. Di 'se crei una nuova directory in django per separare i test unit in più file e posizionali in una directory, devi anche creare il __init__.pyfile accanto a tutti gli altri file nella nuova directory test creata. altrimenti può dare un errore simile 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

Questo è molto più efficace di quanto sopra.

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

dove si {directory-of-.pyc-files}trova la directory che contiene i file Python compilati.


1
Questo nel caso in cui tu abbia i file PY a portata di mano, altrimenti dovrai effettuare il downgrade dell'installazione di Python.
Leon Fedotov,

1
Questo non è ancora sicuro per alcuni casi limite. Inoltre, perché stiamo facendo un'eliminazione ricorsiva quando parliamo di file?
Jerome Baum,

1
Perché stai usando due processi? Anche se find non ha eliminato, potresti comunque eseguirefind /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana il

1
Il comando 'trova' non funzionerà in modo sicuro per i nomi di file con spazi se l'operatore finale -print predefinito viene utilizzato direttamente da xargs rm. Python non importa file con nome non identificativo come questo, ma gli script potrebbero comunque causare l'interruzione e non verranno eliminati. Generalmente sempre più sicuro usare un extra -print0 (zero alla fine) sul comando find (come ultimo parametro prima del simbolo '|' pipe) e quindi l'opzione -0 su xargs (che è un trattino + zero) per capire il - print0 output prima del comando rm, quando il piping trova in xargs.
Breezer,

0

Nel mio caso non era .pycche vecchi .mofile di traduzione binari dopo aver rinominato il mio modulo, quindi all'interno di questa cartella del modulo ho dovuto eseguire

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

(eseguire il backup e provare prima a riparare i .pycfile)


0

Questo può accadere anche se hai il file python27.dll errato (nel caso di Windows), per risolvere questo basta reinstallare (o estrarre) python con la versione esatta corrispondente della dll. Ho avuto un'esperienza simile.


0

Ho appena affrontato lo stesso problema con Fedora26 in cui molti strumenti come il dnf sono stati rotti a causa del cattivo numero magico per sei. Per una ragione sconosciuta ho un file /usr/bin/six.pyc, con il numero magico inaspettato. L'eliminazione di questo file risolve il problema


0

Nel mio caso, ho git cloneuna lib che aveva un interprete di

#!/usr/bin/env python

Mentre pythonconduceva Python2.7anche se il mio codice principale era in esecuzione con python3.6 ... ha comunque creato un *.pycfile per2.7 versione ...

Posso dire che questo errore è probabilmente il risultato di un mix tra le versioni 2.7 e 3+, ecco perché cleanup (in qualsiasi modo puoi pensare a quello che stai usando) - aiuterà qui ...

  • non dimenticare di modificare il codice Python2x -> python 3 ...

-1

Non cancellarli !!! Fino a..........

Trova una versione nella cartella git, svn o copia che funzioni.

Eliminali e recupera tutto .pyc.

Questo è lavoro per me.


eyyy perché ho -1? funziona davvero per me ed ero in una situazione davvero brutta ¬¬
lauralacarra

2
ripristinare la versione precedente non è una soluzione globale
ZiTAL

4
Perché mai commetteresti il ​​tuo *.pyc file?
Manos Kounelakis,

Questo è il solito errore. Quando non si configura il file git ignore correttamente. Quindi do la soluzione e quindi devi ordinare il tuo ingegno.
lauralacarra,

-1

Dovrai eseguire questo comando in ogni percorso che hai nel tuo ambiente.

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

Quindi eseguire il comando in ogni directory qui

find /usr/lib/python3.6/ -name "*.pyc" -delete
find /usr/local/lib/python3.6/dist-packages -name "*.pyc" -delete
# etc...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.