Заставить Python игнорировать файлы .pyc - PullRequest
21 голосов
/ 17 августа 2010

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

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

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

Ответы [ 6 ]

12 голосов
/ 17 августа 2010

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

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

11 голосов
/ 17 августа 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
5 голосов
/ 23 июля 2014

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

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

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

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

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

Если вы не можете удалить все .pycs, тогда вы можете:

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

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

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

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

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

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

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

0 голосов
/ 18 августа 2010

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

0 голосов
/ 17 августа 2010

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

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

0 голосов
/ 17 августа 2010

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

...