Kötü sihirli sayı hatası nedir?


320

Python'da "Kötü büyü numarası" ImportError nedir ve nasıl düzeltebilirim?

Çevrimiçi bulabildiğim tek şey, bunun bir .py -> .pyc dosyasını derlemesinden ve daha sonra yanlış python sürümüyle kullanmaya çalışmasından kaynaklandığını gösteriyor. Benim durumumda, ancak, dosya bazı kez iyi görünüyor ama diğerleri değil gibi görünüyor ve neden emin değilim.

Geri izlemede python'un sağladığı bilgiler özellikle yararlı değildir (bu yüzden burada soruyordum ...), ancak yardımcı olması durumunda:

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

Sorunun oluştuğu kodu verebilir misiniz?
Evan Fosmark

Peki hangi python sürümünü kullanıyorsunuz?
paxdiablo

Normalleştirme dosyalarınızdan biri mi yoksa üçüncü taraflardan biri mi?
paxdiablo

3
Hrm, tamam, sanırım .py dosyasını taşıdığımda uzun zaman önce geride kalan eski bir .pyc dosyasını içe aktarmış olmalıyım ve böylece eski sürümü değil, yeni sürümü içe aktarabilirdim.
Noah

1
Ben eski .pyc dosyasını eksenli, bu yüzden kullanışlı değil, ama benim sorun alma yolları ile oldu - Ben hareket etmeseydi python .pyc dosyasını yeniden oluşturmak için .py dosyasını kullanacağını düşünüyorum (doğru mu?)
Noah

Yanıtlar:


400

Sihirli sayı, bir dosyanın ilk birkaç baytının dosya türünü gösteren bir işaretçi tuttuğu UNIX tipi sistemlerden gelir.

Python, pycoluşturduklarında dosyalarına benzer bir işaretleyici koyar .

Daha sonra python yorumlayıcısı, yüklerken bu numaranın doğru olduğundan emin olur.

Bu sihirli numaraya zarar veren herhangi bir şey probleminize neden olacaktır. Bu, pycdosyayı düzenlemeyi veya pycyorumcunuzdan farklı bir python sürümünden (genellikle daha sonra) çalıştırmaya çalışmayı içerir.

Bunlar sizin pyc dosyalarınızsa, onları silin ve yorumlayıcının pydosyaları yeniden derlemesine izin verin . UNIX tipi sistemlerde bu kadar basit bir şey olabilir:

rm *.pyc

veya:

find . -name '*.pyc' -delete

Bunlar sizin değilse, pydosyaları yeniden derleme için almanız veya pycdosyaları o sihirli değerle çalıştırabilecek bir yorumlayıcı almanız gerekir .

Aralıklı doğaya neden olabilecek bir şey. pycSoruna neden olan sadece belirli koşullar altında ithal edilebilir. Bazen ithalat yapması pek olası değildir. İçe aktarma başarısız olduğunda gerçek tam yığın izlemesini kontrol etmelisiniz?

Bir kenara olarak, tüm ilk kelime 2.5.1(r251:54863) pycdosyalarının olduğu 62131, 2.6.1(r261:67517)olduğunu 62161. Tüm sihirli numaraların listesi Python/import.cburada bulunabilir , bütünlük için çoğaltılabilir (cevabın gönderildiği andaki güncel, o zamandan beri değişmiş olabilir):

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
Teşekkürler - bu doğrudan sorunumu çözmeme yardımcı olmadı, ama yine de cevabı bilmek güzel!
Noah

Soruna hangi pyc dosyasının neden olduğunu nasıl kontrol edebilirim, tüm pyc dosyalarını sildim ama yine de bu hatayı alıyorum.
sunprophit

Belki şimdi 'rm __pycache __ / * pyc' ye ihtiyacınız var, çünkü pyc dosyaları şimdi bu klasörde.
Arpad Horvath

1
Teşekkürler! Bana şu şekilde oluyordu: ERROR: tornado.general: 'es' için çeviri yüklenemiyor: [Errno 0] Kötü sihirli sayı: '/app/locale/es/LC_MESSAGES/django.mo'. Aslında, * .mo doğru şekilde derlenmemişti.
ericson.cepeda


60

Tüm .pyc dosyalarının silinmesi "Kötü Sihirli Numara" hatasını düzeltir.

find . -name "*.pyc" -delete

8
find . -name "*.pyc" -deleteGeçmek için tüm dosya adlarını genişletirseniz boşluklarla (ve muhtemelen çok uzun bir komut satırıyla) sorun yaşayacağınız için kullanmak daha iyidir rm.
Andrew Aylett

25
IMO oldukça tehlikeli bir senaryo. Bir paket, kaynağı kapalı tutmak için yalnızca .pyc dosyalarıyla teslim edilirse ne olur? Hata! Uygulamayı yeni sildiniz.
Dan Mantyla

3
find . -name "*.pyc" -printÜzücü bir şey yapmadığınızı doğruladıktan sonra, sorunlu dosyaları ilk önce çalıştırmak ve ancak o zaman ya sorunlu dosyaları elle silmek ve / veya yukarıdaki komutu çalıştırmak muhtemelen en iyisidir .
michael

9
@DanMantyla Kapalı kaynak paketleri yine de silinmeyi hak ediyor.
kedi

25

Python2 ile oluşturulan bir python3 *.pycdosyası yüklemek de bu hataya neden olur.


3
Bu bir yorum olabilir, cevap değil.
Kroltan

2
@Kroltan yine de bir cevap olarak kabul edilmiş olandan daha iyi. Kısa ve öz.
Antony Hatchkins

@AntonyHatchkins En azından benim görüşüme göre, bu .pyc'nin silinmesini öneren cevapların herhangi biri için bir yorum olabilir. Bu olası bir neden olsa da , farklı bir çözümü yoktur , bu yüzden bu gereksizdir. Katılmıyorum, sadece benim görüşüm.
Kroltan

@Kroltan 'Nasıl düzeltilir' kısmı burada oldukça açıktır. Nedeni, en azından benim için gerçekten ilginç olan şey bu. Farklı python 2.x sürümleri ile çok fazla uğraştım ve .pyc sürümleri arasında herhangi bir uyumsuzlukla karşılaşmadım. Ve bu çözüm bunun python3 ve python2 sorunu olduğunu söylüyor - kabul edilen cevapta bilgi eksik. Artı kısa cevapları seviyorum (mümkünse) :)
Antony Hatchkins

@AntonyHatchkins, bu çözüm bunun bir py2 / 3 sorunu olduğunu söyleyebilir, ancak bu sadece bir olasılıktır ve bu nedenle, ilk versiyonundan bu yana kabul edilen cevapta (paragraf 4) önerilmektedir :-)
paxdiablo

6

Pyc dosyasını bir Windows makinesine götürün. Bu pyc dosyasını açmak için herhangi bir Onaltılı düzenleyici kullanın. Ücretsiz 'HexEdit' kullandım. Şimdi ilk iki baytın onaltılık değerini okuyun. Benim durumumda, bunlar 03 f3 idi.

Calc'i açın ve Onaltılık ve Ondalık dönüşümü görmek için ekran modunu Programcı'ya (XP'de Scientific) dönüştürün. Radyo düğmesinden "Onaltılık" ı seçin. Önce değerleri ikinci bayt, sonra ilk bayt olarak girin, yani f303 Şimdi "Dec" (Ondalık) radyo düğmesine tıklayın. Görüntülenen değer, pitonun sihirli numarasına veya diğer bir versiyonuna karşılık gelen değerdir.

Yani, önceki yanıtta verilen tablo göz önüne alındığında

  • 1.5 => 20121 => 4E99 böylece dosyalar ilk bayt 99 ve ikinci 4e olarak
  • 1.6 => 50428 => C4FC, böylece dosyalar ilk bayt'ı fc ve ikincisi c4 olarak alacaktı

2

Dosyanızı .pyc uzantılı el ile adlandırdıysanız "Kötü büyü numarası" hatası da oluşur


1

Çok eski (1.5.2) bir uygulama kullanarak garip bir kötü sihirli sayı hatası vardı. Bir .pyo dosyası oluşturdum ve bu da hatayı tetikledi. Garip bir şekilde, modülün adı değiştirilerek sorun çözüldü. Rahatsız edici isim sms.py idi. Bu modülden bir sms.pyo oluşturduysam, sonuçta Bad Magic Number hatası oluştu. Adı smst.py olarak değiştirdiğimde hata ortadan kalktı. Sms.py'nin bir şekilde aynı ada sahip başka bir modüle müdahale edip etmediğini görmek için ileri ve geri kontrol ettim, ancak herhangi bir isim çarpışması bulamadım. Bu sorunun kaynağı benim için bir öfke olarak kalsa da, bir modül adı değişikliği denemenizi öneririz.


1

Bunun nedeni __init__.py, dizindeki dosyanın eksik olması olabilir . Django'da birim testlerini birden fazla dosyaya ayırmak için yeni bir dizin oluşturup bunları bir dizine yerleştirdiğinizde __init__.py, yeni oluşturulan test dizinindeki diğer tüm dosyaların yanında da dosya oluşturmanız gerektiğini varsayalım. aksi halde hata verebilir 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

Bu, yukarıdakinden çok daha etkilidir.

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

burada {directory-of-.pyc-files}derlenmiş python dosyalarını içeren dizin.


1
Bu, py dosyalarının elinizde olması durumunda, değilse, python kurulumunu düşürmeniz gerekecektir.
Leon Fedotov

1
Bu bazı uç durumlar için hala güvensizdir. Ayrıca dosyalar hakkında konuşurken özyinelemeli silme neden yapıyoruz?
Jerome Baum

1
Neden iki işlem kullanıyorsunuz? find /dir -name "*.pyc" -exec rm '{}' ';'
Bulma işlemi silinmemiş

1
Varsayılan -print son işleci doğrudan xargs rm tarafından kullanılıyorsa, 'find' komutu boşluklu dosya adları için güvenli bir şekilde çalışmaz. Python, bu gibi tanımlayıcı olmayan dosyaları içe aktarmaz, ancak komut dosyaları bunun bozulmasına neden olabilir ve silinmezler. Genellikle find komutunda fazladan -print0 (uçta sıfır) ('|' boru sembolünden önceki son parametre olarak) ve ardından xargs üzerinde -0 seçeneği (bu bir tire + sıfır) kullanmak daha güvenlidir - rm komutundan önce print0 çıktısı, borular xargs'a geldiğinde.
Breezer

0

Benim durumumda, kendi modülümü yeniden adlandırdıktan sonra .pyceski ikili .moçeviri dosyaları değildi , bu yüzden bu modül klasörü içinde çalıştırmak zorunda kaldım

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

(lütfen yedekleyin ve .pycönce dosyaları düzeltmeyi deneyin )


0

Bu, yanlış python27.dll dosyanız (Windows durumunda) varsa, bu sorunu çözmek için sadece karşılık gelen dll sürümüyle yeniden yükleyin (veya ayıklayın). Buna benzer birşey yaşadım.


0

Fedora26 ile aynı sorunla karşı karşıya kaldım, burada dnf gibi birçok araç altı kişilik sihirli numara nedeniyle kırıldı. Bilinmeyen bir nedenden dolayı /usr/bin/six.pyc dosyasında beklenmedik sihirli numarayla bir dosya var. Bu dosyayı silmek sorunu çözdü


0

Benim durumumda, git clonebir tercümanı olan bir lib'im var

#!/usr/bin/env python

Ana kodum python3.6 ile çalışıyor olmasına rağmen pythonyol açarken Python2.7... hala sürüm *.pyciçin bir dosya oluşturdu 2.7...

Bu hatanın muhtemelen 2.7 ve 3+ sürümleri arasındaki bir karışımın sonucu olduğunu söyleyebilirim, bu yüzden temizleme (kullandığınız herhangi bir şekilde düşünebilirsiniz) - burada yardımcı olacaktır ...

  • bu Python2x kodunu ayarlamayı unutmayın -> python 3 ...

-1

Onları silmeyin !!! A kadar..........

Git, svn veya copy klasöründe çalışan bir sürüm bulun.

Onları silin ve ardından tüm .pyc dosyalarını kurtarın.

Bu benim için iş.


eyyy neden -1 var? gerçekten benim için çalışıyor ve ben gerçekten kötü durumdaydı ¬¬
lauralacarra

2
önceki sürüme geri dönmek global bir çözüm değil
ZiTAL

4
Neden *.pycdosyalarınızı teslim ettiniz ?
Manos Kounelakis

Bu olağan bir hatadır. Git ignore dosyasını doğru yapılandırmazsanız. Ben çözüm vermek ve sonra git sipariş gerekir.
lauralacarra

-1

Bu komutu ortamınızdaki her yolda çalıştırmanız gerekecektir.

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

Sonra buradaki her dizinde komutu çalıştırın

find /usr/lib/python3.6/ -name "*.pyc" -delete
find /usr/local/lib/python3.6/dist-packages -name "*.pyc" -delete
# etc...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.