Заставить Python игнорировать файлы .pyc

Есть ли способ заставить Python игнорировать любые присутствующие файлы .pyc и всегда напрямую интерпретировать весь код (включая импортированные модули)? Google не нашел ответов, так что я подозреваю, что нет, но, похоже, стоит спросить на всякий случай.

(Зачем мне это? У меня есть большой конвейер сценариев Python, которые многократно выполняются на кластере из пары сотен компьютеров. Сами сценарии Python живут в общей файловой системе NFS. раз в течение нескольких часов вдруг начинают крашиться с ошибкой о невозможности импорта модуля.Принудительная перегенерация файла .pyc решает проблему.Хочется, конечно, устранить первопричины, но в тем временем нам также нужно, чтобы система продолжала работать, поэтому кажется, что игнорирование файлов .pyc, если это возможно, было бы разумным обходным путем).

P.S. Я использую Python 2.5, поэтому не могу использовать -B.


person Ryan Gabbard    schedule 17.08.2010    source источник


Ответы (6)


Вы можете использовать модуль imp стандартной библиотеки Python для повторной реализации __builtins__.__import__, которая представляет собой функцию ловушки, вызываемую операторами import и from. В частности, для загрузки .py можно использовать функцию imp.load_module. даже если присутствует соответствующий .pyc. Обязательно внимательно изучите все документы на странице, на которую я указал, а также документы для импорт, так как это довольно тонкая работа. Сами документы предлагают вместо этого использовать перехватчики импорта (согласно PEP 302), но для этой конкретной задачи я подозреваю, что это будет еще сложнее.

Кстати, вероятные причины наблюдаемых вами проблем включают в себя состояние гонки между разными компьютерами, пытающимися одновременно записать .pyc файлов - блокировка NFS общеизвестно ненадежна и всегда была ;-). Пока все компиляторы Python, которые вы используете, имеют одну и ту же версию (если нет, у вас все равно большие проблемы ;-), я бы предпочел предварительно скомпилировать все эти .py файлы в .pyc и сделать их каталоги доступными только для чтения; последнее в любом случае кажется самым простым подходом (вместо взлома __import__), даже если по какой-то причине вы не можете выполнить предварительную компиляцию.

person Alex Martelli    schedule 17.08.2010

Это не совсем то, о чем вы просили, но можно ли удалить существующие файлы .pyc, а затем не создавать для вас больше работы? В этом случае вы можете использовать опцию -B:

>python --help
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
person Blair Conrad    schedule 17.08.2010
comment
На самом деле это было бы здорово, за исключением того, что, к сожалению, по независящим от меня причинам я застрял на Python 2.5, в котором нет -B. Надо было упомянуть об этом в вопросе, извините! - person Ryan Gabbard; 17.08.2010

Если кто-то использует python 2.6 или выше с тем же вопросом, самое простое:

  1. Удалить все файлы .pyc
  2. Запустите все ваши интерпретаторы Python с параметром -B, чтобы они не генерировали файлы .pyc.

Из документов:

-B Если указано, Python не будет пытаться записывать файлы .pyc или .pyo при импорте исходных модулей. См. также PYTHONDONTWRITEBYTECODE.

Новое в версии 2.6.

Если вы не можете удалить все файлы .pyc, вы можете:

1) Запустите все ваши интерпретаторы Python с параметрами -B -O.

Это укажет python искать файлы .pyo для байт-кода вместо файлов .pyc (-O) и скажет python не создавать файлы байт-кода (-B).

Комбинация двух вариантов, если вы не использовали их раньше, заключается в том, что Python не будет генерировать файлы байт-кода и не будет искать файлы байт-кода, которые были бы созданы при более старых запусках.

Из документов:

-B Если указано, Python не будет пытаться записывать файлы .pyc или .pyo при импорте исходных модулей. См. также PYTHONDONTWRITEBYTECODE.

Новое в версии 2.6.

-O Включить базовую оптимизацию. Это изменяет расширение имени файла для скомпилированных (байт-код) файлов с .pyc на .pyo. См. также PYTHONOPTIMIZE.

person mtd    schedule 23.07.2014

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

person Justin Ethier    schedule 17.08.2010

Ну, я не думаю, что Python когда-либо интерпретирует код напрямую, если вы загружаете код из файла. Даже при использовании интерактивной оболочки Python скомпилирует импортированный модуль в файл .pyc.

Тем не менее, вы можете написать сценарий оболочки, чтобы удалить все файлы .pyc перед запуском ваших сценариев. Это, безусловно, приведет к полной перестройке перед каждым выполнением.

person quanticle    schedule 17.08.2010

Вы можете обнаружить, что PEP 3147 – каталоги репозиториев PYC могут представлять большой интерес для Python 3.2 и выше.

person Matt Joiner    schedule 18.08.2010