Что за ошибка с магическим числом?

320

Что такое «Неправильное магическое число» ImportError в python, и как мне это исправить?

Единственное, что я могу найти в Интернете, говорит о том, что это вызвано компиляцией файла .py -> .pyc и последующей попыткой использовать его с неправильной версией python. В моем случае, однако, файл, кажется, импортирует нормально в некоторых случаях, но не в других, и я не уверен, почему.

Предоставление питоном информации в трассировке не особенно полезно (вот почему я спрашивал здесь ...), но здесь это на случай, если это поможет:

Traceback (most recent call last):
  File "run.py", line 7, in <module>
    from Normalization import Normalizer
Ной
источник
Не могли бы вы предоставить код, в котором возникает проблема?
Эван Фосмарк
А какую версию Python вы используете?
paxdiablo
И нормализация - это один из ваших файлов или сторонний?
paxdiablo
3
Хм, хорошо, я думаю, что я, должно быть, импортировал старый файл .pyc, который был оставлен давно, когда я переместил файл .py, и поэтому я мог импортировать новую версию, но не старую.
Ной
1
Я удалил старый файл .pyc, поэтому он мне не пригодился, но моя проблема была в путях импорта - я думаю, что python использовал бы файл .py для воссоздания файла .pyc, если бы я его не переместил (это верно?)
Ной

Ответы:

401

Магическое число происходит из систем типа 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файлов 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
paxdiablo
источник
2
Спасибо - это не помогло мне разобраться в моей проблеме, но в любом случае приятно знать ответ!
Ноя
Как я могу проверить, какой pyc-файл вызывает проблему, я удалил все pyc-файлы, но все еще получаю эту ошибку.
всепроникающий
Возможно, вам сейчас нужен rm __pycache __ / * pyc, потому что файлы pyc теперь находятся в этой папке.
Арпад Хорват
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
Дейви,
60

Удаление всех файлов .pyc исправит ошибку «Bad Magic Number».

find . -name "*.pyc" -delete
Akarca
источник
8
Вероятно, лучше использовать find . -name "*.pyc" -delete, так как у вас будут проблемы с пробелами (и, возможно, со слишком длинной командной строкой), если вы развернете все имена файлов для передачи rm.
Эндрю Айлетт
25
ИМО это довольно опасный сценарий. Что если пакет был доставлен только с файлами .pyc, чтобы он оставался закрытым? К сожалению, вы только что удалили приложение.
Дэн Мантила
3
Вероятно, лучше всего сначала запустить find . -name "*.pyc" -printи только потом либо удалить проблемные файлы вручную, и / или выполнить указанную выше команду, убедившись, что вы не делаете что-то прискорбное.
Майкл
9
@DanMantyla Закрытые исходные пакеты в любом случае заслуживают удаления.
кошка
25

Загрузка файла, сгенерированного python3, *.pycс python2 также вызывает эту ошибку.

JTM
источник
3
Это может быть комментарий, а не ответ.
Кролтан
2
@Kroltan, тем не менее, это чертовски хороший ответ, лучше принятого. Краткий и точный.
Энтони Хэтчкинс
@AntonyHatchkins По крайней мере, на мой взгляд, это может быть комментарий к любому из ответов, предлагающих удаление .pyc. Несмотря на то, что это одна из возможных причин , у нее нет другого решения , так что это избыточно. Не стесняйтесь не соглашаться, только мое мнение.
Кролтан
@Kroltan Часть «как исправить» здесь довольно очевидна. Причина, вот что действительно интересно - по крайней мере, для меня - это. Я много работал с разными версиями Python 2.x и никогда не сталкивался с несовместимостью между версиями .pyc. И это решение говорит о том, что это проблема python3 vs python2 - информация отсутствует в принятом ответе. Плюс я люблю короткие ответы (где это возможно) :)
Энтони Хэтчкинс
@AntonyHatchkins, это решение вполне может говорить о том, что это проблема py2 / 3, но это только одна возможность, и, в этом отношении, один предложенный в принятом ответе (параграф 4) начиная с самой его первой версии :-)
paxdiablo
6

Возьмите файл pyc на машину с Windows. Используйте любой Hex-редактор, чтобы открыть этот pyc-файл. Я использовал бесплатное программное обеспечение «HexEdit». Теперь прочитайте шестнадцатеричное значение первых двух байтов. В моем случае это были 03 f3.

Откройте calc и преобразуйте его режим отображения в Programmer (Scientific in XP), чтобы увидеть шестнадцатеричное и десятичное преобразование. Выберите «Hex» из переключателя. Введите значения в качестве второго байта, а затем первого байта, т.е. f303 Теперь нажмите кнопку «Dec» (десятичное число). Отображаемое значение соответствует магическому числу, известному как версия python.

Итак, учитывая таблицу, приведенную в предыдущем ответе

  • 1.5 => 20121 => 4E99, поэтому файлы будут иметь первый байт как 99, а второй как 4e
  • 1.6 => 50428 => C4FC, поэтому файлы будут иметь первый байт как fc, а второй как c4
Санджай Чопра
источник
2

Ошибка «Bad magic number» также возникает, если вы вручную назвали свой файл с расширением .pyc

Deke
источник
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}каталог, содержащий скомпилированные файлы Python.

ozgurv
источник
1
Это в том случае, если у вас есть py-файлы под рукой, если нет, то вам придется понизить версию Python.
Леон Федотов
1
Это все еще небезопасно для некоторых крайних случаев. Кроме того, почему мы делаем рекурсивное удаление, когда говорим о файлах?
Джером Баум
1
Почему вы используете два процесса? Даже если в find не было find /dir -name "*.pyc" -exec rm '{}' ';'
удалено
1
Команда 'find' не будет работать безопасно для имен файлов с пробелами, если конечный оператор -print по умолчанию используется непосредственно xargs rm. Python не импортирует неименованные именованные файлы, как это, но сценарии все равно могут привести к его поломке, и они не будут удалены. Как правило, всегда безопаснее использовать дополнительный -print0 (ноль в конце) в команде поиска (в качестве последнего параметра перед символом канала '|') и затем параметр -0 в xargs (то есть дефис + ноль), чтобы понять - вывод print0 перед командой rm, при конвейере находи в xargs.
Бризер
0

В моем случае это были не .pycстарые двоичные .moфайлы перевода после того, как я переименовал свой собственный модуль, так что внутри этой папки модуля мне пришлось запустить

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

(пожалуйста, сделайте резервную копию и попробуйте .pycсначала исправить файлы)

d9k
источник
0

Это также может произойти, если у вас неправильный файл python27.dll (в случае Windows), чтобы решить эту проблему, просто переустановите (или распакуйте) python с точной соответствующей версией dll. У меня был похожий опыт.

Ibrahim.H
источник
0

Я только что столкнулся с той же проблемой с Fedora26, где многие инструменты, такие как dnf, были сломаны из-за неправильного магического числа для шести. По неизвестной причине у меня есть файл /usr/bin/six.pyc с неожиданным магическим числом. Удаление этого файла решит проблему

Zedge
источник
0

В моем случае у меня git cloneесть библиотека, в которой есть переводчик

#!/usr/bin/env python

Хотя pythonэто и привело к тому, Python2.7что мой основной код работал с python3.6 ... он все же создал *.pycфайл для 2.7версии ...

Я могу сказать, что эта ошибка, вероятно, является результатом смешения версий 2.7 и 3+, поэтому очистка (в любом случае вы можете думать о том, что вы используете) - поможет здесь ...

  • не забудьте настроить этот код Python2x -> Python 3 ...
Рики Леви
источник
-1

Не удаляйте их !!! До того как..........

Найдите версию в вашей папке git, svn или copy, которая работает.

Удалите их, а затем восстановите все .pyc.

Это работа для меня.

lauralacarra
источник
эййу, почему у меня -1? это действительно работает для меня, и я был в очень плохом положении ¬¬
lauralacarra
2
возврат к предыдущей версии не является глобальным решением
ZiTAL
4
Зачем вам когда-нибудь фиксировать свои *.pycфайлы?
Манос Кунелакис
Это обычная ошибка. Если вы не настроили git, игнорируйте файл правильно. Поэтому я даю решение, а затем вы должны заказать свой мерзавец.
Лауралакарра
-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...
Ahmed
источник