Я понимаю, что файлы «.pyc» представляют собой скомпилированные версии файлов «.py» в виде обычного текста, созданные во время выполнения, чтобы программы работали быстрее. Однако я заметил несколько вещей:
- При модификации файлов "py" поведение программы меняется. Это указывает на то, что файлы "py" скомпилированы или, по крайней мере, проходят какой-то процесс хеширования или сравнивают временные метки, чтобы определить, нужно ли их перекомпилировать.
- После удаления всех файлов ".pyc" (
rm *.pyc
) иногда поведение программы меняется. Это означает, что они не компилируются при обновлении файлов ".py".
Вопросы:
- Как они решают, когда их компилировать?
- Есть ли способ обеспечить более строгую проверку во время разработки?
python
python-internals
pyc
Аарон Шиф
источник
источник
rm *.pyc
. Это не приведет к удалению файлов .pyc во вложенных папках. Использоватьfind . -name '*.pyc' -delete
вместоОтветы:
Эти
.pyc
файлы создаются (и , возможно , переписаны) только тогда , когда этот файл питон импортируется какой - либо другой сценарий. Если вызывается импорт, Python проверяет,.pyc
не старше ли внутренняя метка времени файла, чем соответствующий.py
файл. Если это так, он загружает.pyc
; если это не так или если.pyc
он еще не существует, Python компилирует.py
файл в.pyc
и загружает его.Что вы имеете в виду под «более строгой проверкой»?
источник
rm *.pyc
. Я знаю, что если я принудительно воссоздаю все файлы, некоторые проблемы будут исправлены, что означает, что файлы не перекомпилируются сами по себе. Я полагаю, что если они используют временные метки, то нет способа сделать это поведение более строгим, но проблема все еще сохраняется..pyc
«метка времени ДОЛЖНО быть старше , чем соответствующий.py
» метки времени s , чтобы вызвать перекомпиляции.Файлы .pyc, создаваемые при импорте соответствующих элементов кода, и обновляются, если соответствующие файлы кода были обновлены. Если файлы .pyc удалены, они будут автоматически восстановлены. Однако они не удаляются автоматически при удалении соответствующих файлов кода.
Это может вызвать некоторые действительно забавные ошибки во время рефакторинга на уровне файлов.
Прежде всего, вы можете отправить код, который работает только на вашем компьютере и ни на каком другом. Если у вас есть висящие ссылки на удаленные вами файлы, они все равно будут работать локально, если вы не удалите вручную соответствующие файлы .pyc, поскольку файлы .pyc можно использовать при импорте. Это усугубляется тем фактом, что правильно настроенная система контроля версий будет отправлять только файлы .py в центральный репозиторий, а не файлы .pyc, а это означает, что ваш код может пройти «тест на импорт» (все ли импортируются правильно) нормально, а не работать на чужом компьютере.
Во-вторых, вы можете столкнуться с ужасными ошибками, если превратите пакеты в модули. Когда вы конвертируете пакет (папку с
__init__.py
файлом) в модуль (файл .py), файлы .pyc, которые когда-то представляли этот пакет, остаются. В частности,__init__.pyc
осталось. Итак, если у вас есть пакет foo с каким-то кодом, который не имеет значения, то позже удалите этот пакет и создайте файл foo.py с некоторой функциейdef bar(): pass
и запустите:from foo import bar
Вы получаете:
ImportError: cannot import name bar
потому что python все еще использует старые файлы .pyc из пакета foo, ни один из которых не определяет bar. Это может быть особенно проблематично на веб-сервере, где полностью работающий код может сломаться из-за файлов .pyc.
В результате обеих этих причин (и, возможно, других) ваш код развертывания и тестовый код должны удалить файлы .pyc, например, со следующей строкой bash:
find . -name '*.pyc' -delete
Кроме того, начиная с python 2.6, вы можете запускать python с
-B
флагом, чтобы не использовать файлы .pyc. См. Как избежать файлов .pyc? Больше подробностей.См. Также: Как удалить все файлы .pyc из проекта?
источник
__init__.py
файлом) ...». Это будет пакет, а не модуль.__init__.pyc
осталось. - Как придешь? Поскольку пакет - это каталог, то удаление пакета означает удаление каталога, поэтому файлов не осталось….pyc
проблема также является одной из причин: скрытые зависимости от ОС и уровней исправлений утилит,.so
файлов , файлов конфигурации, других библиотек Python (если вы не работаете в виртуальном окружении), непонятных переменных env ... список можно продолжать. Чтобы быть тщательным и найти все подобные проблемы, вам нужно сделать чистую копию вашего кода в репозитории git или опубликовать как пакет на сервере в стиле PyPi и выполнить полное клонирование или настройку на новой виртуальной машине. Некоторые из этих потенциальных проблем делают эту.pyc
проблему бледной по сравнению с этим.