ข้อผิดพลาดเกี่ยวกับเลขเวทย์ที่ไม่ดีคืออะไร


320

"หมายเลขมายากลไม่ถูกต้อง" ImportError ในงูหลามคืออะไรและฉันจะแก้ไขได้อย่างไร

สิ่งเดียวที่ฉันสามารถค้นหาออนไลน์ได้แสดงให้เห็นว่าเกิดจากการคอมไพล์ไฟล์. py -> .pyc จากนั้นพยายามใช้กับไพ ธ อนผิดเวอร์ชัน อย่างไรก็ตามในกรณีของฉันไฟล์ดูเหมือนว่าจะนำเข้าได้บางครั้ง แต่ไม่ใช่ไฟล์อื่นและฉันไม่แน่ใจว่าทำไม

ข้อมูลของงูเหลือมที่ให้ไว้ในการสืบค้นกลับไม่เป็นประโยชน์อย่างยิ่ง (ซึ่งเป็นสาเหตุที่ฉันถามที่นี่ ... ) แต่ที่นี่มันมีประโยชน์ในกรณีที่:

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

คุณสามารถระบุรหัสที่เกิดปัญหาได้หรือไม่
Evan Fosmark

คุณใช้ไพ ธ อนรุ่นใด?
paxdiablo

และเป็นมาตรฐานหนึ่งในไฟล์ของคุณหรือบุคคลที่สาม?
paxdiablo

3
โอเคฉันคิดว่าฉันต้องนำเข้าไฟล์. pyc เก่าที่ทิ้งไว้นานแล้วเมื่อฉันย้ายไฟล์. py ดังนั้นฉันจึงสามารถนำเข้าเวอร์ชันใหม่ได้ แต่ไม่ใช่ไฟล์เก่า
โนอาห์

1
ฉัน axed ไฟล์. pyc เก่าดังนั้นฉันจึงไม่สะดวก แต่ปัญหาของฉันคือเส้นทางการนำเข้า - ฉันคิดว่าหลามจะใช้ไฟล์. py เพื่อสร้างไฟล์. pyc ขึ้นใหม่ถ้าฉันไม่ย้าย (ถูกไหม?)
โนอาห์

คำตอบ:


400

หมายเลขเวทย์มนตร์นั้นมาจากระบบประเภท UNIX ซึ่งสองสามไบต์แรกของไฟล์ที่มีเครื่องหมายระบุประเภทของไฟล์

Python ใส่เครื่องหมายที่คล้ายกันลงใน pycไฟล์เมื่อสร้างขึ้น

จากนั้นล่ามไพ ธ อนทำให้แน่ใจว่าหมายเลขนี้ถูกต้องเมื่อทำการโหลด

อะไรก็ตามที่สร้างความเสียหายให้กับหมายเลขเวทมนต์นี้จะทำให้เกิดปัญหาของคุณ ซึ่งรวมถึงการแก้ไขpycไฟล์หรือพยายามเรียกใช้pycไพ ธ อนรุ่นอื่น (โดยปกติภายหลัง) กว่าล่ามของคุณ

หากเป็นไฟล์ของคุณ pycให้ลบออกและให้ล่ามทำการรวบรวมpyไฟล์ใหม่อีกครั้ง บนระบบชนิด UNIX ที่อาจเป็นอะไรที่ง่ายเพียง:

rm *.pyc

หรือ:

find . -name '*.pyc' -delete

หากไม่ใช่ของคุณคุณจะต้องได้รับpyไฟล์สำหรับการรวบรวมซ้ำหรือล่ามที่สามารถเรียกใช้pycไฟล์ด้วยค่าเวทย์มนตร์นั้น

สิ่งหนึ่งที่อาจทำให้ธรรมชาติไม่ต่อเนื่อง สิ่งpycที่ทำให้เกิดปัญหาอาจถูกนำเข้าภายใต้เงื่อนไขบางประการเท่านั้น มันไม่น่าเป็นไปได้สูงที่มันจะนำเข้าในบางครั้ง คุณควรตรวจสอบการติดตามสแต็คเต็มจริงเมื่อการนำเข้าล้มเหลว?

เช่นกันคำแรกของฉันทั้งหมด2.5.1(r251:54863) pycไฟล์62131, คือ2.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
ขอบคุณ! มันเกิดขึ้นกับฉันด้วย: ข้อผิดพลาด: tornado.general: ไม่สามารถโหลดการแปลสำหรับ 'es': [Errno 0] หมายเลขเวทย์มนตร์แย่: '/app/locale/es/LC_MESSAGES/django.mo' ในความเป็นจริงมันเป็น * .mo ที่รวบรวมไม่ถูกต้อง
ericson.cepeda

1
รายการอื่น ๆ เพิ่มเติมที่นี่: github.com/google/pytype/blob/master/pytype/pyc/magic.py
Davy

60

การลบไฟล์. pyc ทั้งหมดจะแก้ไขข้อผิดพลาด "Bad Magic Number"

find . -name "*.pyc" -delete

8
มันอาจจะดีกว่าที่จะใช้find . -name "*.pyc" -deleteเป็นคุณจะมีปัญหาเกี่ยวกับช่องว่าง (และอาจจะมีความยาวเกินไปบรรทัดคำสั่ง) rmถ้าคุณขยายชื่อไฟล์ทั้งหมดที่จะผ่านไป
Andrew Aylett

25
IMO นั้นเป็นสคริปต์ที่ค่อนข้างอันตราย จะเกิดอะไรขึ้นถ้าแพ็คเกจถูกส่งด้วยไฟล์. pyc เท่านั้นเพื่อให้มันปิดแหล่งที่มา? โอ๊ะโอคุณเพิ่งลบแอปพลิเคชัน
Dan Mantyla

3
อาจดีที่สุดที่จะเรียกใช้ครั้งแรกfind . -name "*.pyc" -printและจากนั้นลบไฟล์ที่มีปัญหาด้วยตนเองและ / หรือเรียกใช้คำสั่งด้านบนหลังจากตรวจสอบว่าคุณไม่ได้ทำอะไรที่น่าเศร้า
ไมเคิล

9
@DanMantyla แพคเกจแหล่งที่มาปิดสมควรได้รับการลบต่อไป
แมว

25

การโหลด*.pycไฟล์ที่สร้างด้วยpython3 ด้วย python2 ทำให้เกิดข้อผิดพลาดนี้เช่นกัน


3
นี่อาจเป็นความเห็นไม่ใช่คำตอบ
Kroltan

2
@Kroltan แต่ก็เป็นคำตอบที่ดีกว่าคำตอบที่ยอมรับ กระชับและตรงประเด็น
Antony Hatchkins

@AntonyHatchkins อย่างน้อยในมุมมองของฉันนี้อาจเป็นความเห็นเกี่ยวกับคำตอบใด ๆ ที่แนะนำการลบ. pyc แม้ว่านี่จะเป็นสาเหตุหนึ่งที่เป็นไปได้แต่ก็ไม่มีวิธีแก้ปัญหาที่แตกต่างกันดังนั้นนี่จึงซ้ำซ้อน รู้สึกไม่เห็นด้วยเพียงความเห็นของฉัน
Kroltan

@Kroltan ส่วน 'วิธีแก้ไข' ค่อนข้างชัดเจนที่นี่ สาเหตุนั่นคือสิ่งที่น่าสนใจจริงๆ - อย่างน้อยสำหรับฉัน - คือ ฉันทำเรื่องยุ่ง ๆ มากมายกับ python เวอร์ชั่น 2.x ที่แตกต่างกันและไม่เคยเจอกับความไม่ลงรอยกันใด ๆ ระหว่าง. pyc และวิธีนี้บอกว่ามันเป็นปัญหาของ python3 กับ python2 - ข้อมูลหายไปในคำตอบที่ยอมรับ ฉันรักคำตอบสั้น ๆ (ถ้าเป็นไปได้) :)
Antony Hatchkins

@ AntonyHatchkins วิธีนี้อาจบอกได้ว่ามันเป็นปัญหา py2 / 3 แต่เป็นเพียงความเป็นไปได้เพียงอย่างเดียวและสำหรับเรื่องนั้นหนึ่งข้อเสนอแนะในคำตอบที่ได้รับการยอมรับ (วรรค 4) ตั้งแต่รุ่นแรก :-)
paxdiablo

6

นำไฟล์ pyc ไปยังเครื่อง windows ใช้โปรแกรมแก้ไข Hex ใด ๆ เพื่อเปิดไฟล์ pyc นี้ ฉันใช้ freeware 'HexEdit' ตอนนี้อ่านค่าฐานสิบหกสองไบต์แรก ในกรณีของฉันนี่คือ 03 f3

เปิดคำนวณและแปลงโหมดการแสดงผลเป็นโปรแกรมเมอร์ (วิทยาศาสตร์เป็น XP) เพื่อดูการแปลงเลขฐานสิบและทศนิยม เลือก "Hex" จากปุ่มตัวเลือก ป้อนค่าเป็นไบต์ที่สองก่อนจากนั้นจึงเลือกไบต์แรกเช่น f303 ตอนนี้คลิกที่ปุ่มตัวเลือก "Dec" (ทศนิยม) ค่าที่แสดงเป็นค่าที่สอดคล้องกับหมายเลขอาคาของ python

ดังนั้นให้พิจารณาตารางที่ให้ไว้ในคำตอบก่อนหน้า

  • 1.5 => 20121 => 4E99 ดังนั้นไฟล์จะมีไบต์แรกเท่ากับ 99 และวินาทีเป็น 4e
  • 1.6 => 50428 => C4FC ดังนั้นไฟล์จะมีไบต์แรกเป็น fc และวินาทีเป็น c4

2

ข้อผิดพลาด "หมายเลข Magic Bad" จะเกิดขึ้นหากคุณตั้งชื่อไฟล์ด้วยนามสกุล. pyc ด้วยตนเอง


1

ฉันมีข้อผิดพลาด Bad Magic Number ที่แปลกประหลาดโดยใช้การนำมาใช้ (1.5.2) ที่เก่ามาก ฉันสร้างไฟล์. pyo และทำให้เกิดข้อผิดพลาด ปัญหาได้รับการแก้ไขโดยการเปลี่ยนชื่อของโมดูล ชื่อที่ละเมิดคือ sms.py หากฉันสร้าง sms.pyo จากโมดูลนั้นข้อผิดพลาด Bad Magic Number ก็คือผลลัพธ์ เมื่อฉันเปลี่ยนชื่อเป็น 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}เป็นไดเรกทอรีที่มีไฟล์ไพ ธ อนที่คอมไพล์แล้ว


1
ในกรณีที่คุณมีไฟล์ py อยู่ในมือหากไม่ใช่คุณจะต้องปรับลดรุ่นการติดตั้งไพ ธ อน
Leon Fedotov

1
นี่ยังไม่ปลอดภัยสำหรับบางกรณีของขอบ นอกจากนี้ทำไมเราถึงทำการลบแบบเรียกซ้ำเมื่อเราพูดถึงไฟล์?
Jerome Baum

1
ทำไมคุณถึงใช้สองกระบวนการ แม้ว่าการค้นหาไม่ได้ลบคุณยังสามารถเรียกใช้ได้find /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana

1
คำสั่ง 'find' จะไม่ทำงานอย่างปลอดภัยสำหรับชื่อไฟล์ที่มีช่องว่างหาก xargs rm เริ่มต้นใช้ตัวดำเนินการเริ่มต้นสุดท้ายโดยตรง Python ไม่ได้นำเข้าไฟล์ที่ไม่มีชื่อระบุเช่นนี้ แต่สคริปต์ยังสามารถทำให้สิ่งนี้แตกได้และจะไม่ถูกลบ โดยทั่วไปปลอดภัยกว่าที่จะใช้พิเศษ -print0 (ศูนย์ที่จุดสิ้นสุด) ในคำสั่ง find (เป็นพารามิเตอร์สุดท้ายก่อนที่สัญลักษณ์ท่อ '|') และตัวเลือก -0 ใน xargs (นั่นคือยัติภังค์ + ศูนย์) เพื่อทำความเข้าใจ - print0 เอาต์พุตก่อนคำสั่ง rm เมื่อ piping find เป็น xargs
Breezer

0

ในกรณีของฉันมันไม่ใช่.pycแต่.moไฟล์การแปลไบนารีเก่า ๆหลังจากฉันเปลี่ยนชื่อโมดูลของตัวเองดังนั้นภายในโฟลเดอร์โมดูลนี้ฉันต้องเรียกใช้

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

(โปรดสำรองข้อมูลและพยายามแก้ไข.pycไฟล์ก่อน)


0

สิ่งนี้สามารถเกิดขึ้นได้หากคุณมีไฟล์ python27.dll ที่ไม่ถูกต้อง (ในกรณีของ Windows) เพื่อแก้ปัญหานี้เพียงติดตั้งใหม่ (หรือแยก) ไพ ธ อนด้วยเวอร์ชั่น dll ที่สอดคล้องกัน ฉันมีประสบการณ์ที่คล้ายกัน


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 ทั้งหมด

นั่นเป็นผลสำหรับฉัน


ทำไมฉันถึงมี -1 มันใช้งานได้จริงสำหรับฉันและฉันตกอยู่ในสถานการณ์ที่เลวร้ายจริงๆ¬¬
lauralacarra

2
การแปลงกลับเป็นเวอร์ชันก่อนหน้าไม่ใช่โซลูชันระดับโลก
ZiTAL

4
ทำไมคุณถึงส่ง*.pycไฟล์ของคุณ ?
Manos Kounelakis

นั่นเป็นข้อผิดพลาดปกติ เมื่อคุณไม่ได้กำหนดค่าไฟล์ละเว้นการคอมไพล์อย่างถูกต้อง ดังนั้นฉันจึงให้ทางออกแล้วคุณต้องสั่งคอมไพล์ของคุณ
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...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.