Как скомпилировать файлы Python в отдельной папке?

Возможно ли, чтобы Python сохранял файлы .pyc в отдельной папке, которая находится в sys.path?

/code
    foo.py
    foo.pyc
    bar.py
    bar.pyc

К:

/code
   foo.py
   bar.py
/code_compiled
   foo.pyc
   bar.pyc

Я бы хотел этого, потому что считаю, что это будет более организованно. Спасибо за любую помощь, которую вы можете мне оказать.

Как вы пробовали Python 3.2? Он реализует PEP 3147: каталоги репозитория PYC (python.org/dev/peps/pep-3147).

Noctis Skytower 07.08.2012 20:27

Если вам не нужны файлы .pyc, вы можете использовать os.system('del *.pyc') (например, Windows) в конце вашего скрипта.

Charles 26.07.2016 18:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
30
2
13 397
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Ответ принят как подходящий

Обновлять:

В Python 3.8 опция командной строки -X pycache_prefix=PATH позволяет записывать файлы .pyc в параллельное дерево с корнем в данном каталоге, а не в дерево кода. См. $PYTHONPYCACHEPREFIX envvarcredits: @RobertT' answer

Местоположение кэша указывается в sys.pycache_prefix (None указывает местоположение по умолчанию в подкаталогах __pycache__ [начиная с Python 3.2]).

Чтобы отключить кеширование скомпилированного байт-кода Python, можно установить -B, тогда Python не будет пытаться записывать файлы .pyc при импорте исходных модулей. См. $PYTHONDONTWRITEBYTECODE envvarcredits: @Maleev's answer


Old [Python 2] answer:

Есть PEP 304: Управление генерацией файлов байт-кода. Его статус - Withdrawn, и соответствующий пластырь отклонен. Следовательно, прямого способа сделать это может и не быть.

Если вам не нужен исходный код, вы можете просто удалить файлы *.py. Файлы *.pyc могут использоваться как есть или упакованы в яйцо.

Вы можете отредактировать свой ответ, добавив что-нибудь проницательное об обновлении.

Prof. Falken 10.09.2012 17:49

Err. Смотрите дальше вниз. Краткого ответа нет, кроме действительно хитрости в Python 2.x; тривиально в Python 3.2 и новее.

Charles Merriam 10.05.2013 10:00

«Я чувствую, что это было бы более организовано» Почему? Как? Что вы пытаетесь достичь?

Смысл сохранения вывода компилятора состоит в том, чтобы сэкономить крошечный бит времени загрузки при импорте модуля. Зачем все усложнять? Если вам не нравятся файлы .pyc, периодически запускайте сценарий «удалить все .pyc».

Они не важны; они полезны. Зачем отключать эту помощь?

Это не C, C++ или Java, где конечные объекты важны. Это просто кеш, который использует Python. Мы помечаем их как «игнорируемые» в Subversion, чтобы случайно их не отметили.

> Почему? Видимо потому, что они делают вывод ls или список файлов Windows Explorer более загроможденным. Субъективная, но вполне законная озабоченность, не так ли?

Maleev 05.06.2010 15:37

@Maleev: "визуально загроможден"? Проводник можно отсортировать по типу файла, чтобы поместить файлы .pyc в другое место. Linux ls можно использовать с подстановочным знаком (например, ls *.py). Попытка переупорядочить файлы - это большая трата времени, когда вам нужны тривиальные способы уменьшить визуальный беспорядок.

S.Lott 06.06.2010 17:16

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

Samuel A. Falvo II 28.01.2015 02:54

Гвидо не согласен. См. Ветку обсуждения на PEP 3147, где именно эта проблема была исправлена ​​- он говорит, что самый большой аргумент в пользу этой функции - это исправить беспорядок. Спустившись вниз по этой рассылке, вы найдете комментарий Гвидо «это главный аргумент в пользу этого PEP!» в отношении того, как файлы будут менее загромождены / лучше организованы. mail.python.org/pipermail/python-dev/2010-April/099414.html

ArtOfWarfare 09.04.2015 16:28

Я согласен, распространение кода в виде яйца - отличный способ сохранить его организованность. Что может быть более организованным, чем один файл, содержащий весь код и метаданные, которые вам когда-либо понадобятся. Изменение способа работы компилятора байт-кода только вызовет путаницу.

Если вам действительно не нравится расположение этих файлов pyc, альтернативой является запуск из папки, доступной только для чтения. Поскольку python не сможет писать, файлы pyc никогда не создаются. Суть в том, что каждый файл python придется перекомпилировать, как только он будет загружен, независимо от того, изменили вы его или нет. Это означает, что ваше время запуска будет намного хуже.

Я не согласен. Причины неверны или, по крайней мере, плохо сформулированы; но направление действительно. Есть веские причины для отделения исходного кода от скомпилированных объектов. Вот некоторые из них (со всеми я сталкивался в тот или иной момент):

  • встроенное устройство, считывающее из ПЗУ, но способное использовать файловую систему в оперативной памяти.
  • Среда разработки multi-os означает совместное использование (с samba / nfs / всем остальным) моего рабочего каталога и создание на нескольких платформах.
  • коммерческая компания желает распространять pyc только для защиты IP
  • легко запустить набор тестов для нескольких версий Python, используя один и тот же рабочий каталог
  • легче очистить переходные файлы (rm -rf $ OBJECT_DIR вместо find. -name '* .pyc' -exec rm -f {} \;)

Для всех этих проблем есть обходные пути, НО в основном это обходные пути, а НЕ решения. Правильным решением в большинстве этих случаев было бы, чтобы программное обеспечение приняло альтернативное место для хранения и поиска этих переходных файлов.

Если вы готовы пожертвовать генерацией байт-кода ради этого, есть флаг командной строки:

python -B file_that_imports_others.py

Может быть помещен в настройки сборки / запуска IDE

Есть постоянный бодр, который будет включить создание байт-кода в волшебный каталог.

В основном все файлы python будут скомпилированы в каталог __pythoncache__.

Поскольку Python 3.2 был реализован, PEP 3147: это означает, что все файлы .pyc создаются внутри каталога __pycache__ (будет каталог __pycache__ для каждого каталога, в котором есть файлы Python, и он будет содержать файлы .pyc для каждой используемой версии Python. по источникам)

В мрачные и древние дни 2003 года появился PEP 304, чтобы бросить вызов этой проблеме. Его заплатка была признана недостающей. Зависимости платформы переменных среды и перекосы версий разорвали ее в клочья и оставили разбросанными по пустошам.

После долгих лет страданий в последние дни 2009 года появился новый претендент. Барри Варшава вызвал PEP 3147 и отправил его в бой, умело владея простым оружием. PEP раздавил загроможденные файлы PYC, заставил замолчать настораживающий интерпретатор Unladen Swallow и CPython, каждый из которых пытался убедить, что его файл PYC должен победить, и позволил Python расслабиться с его мертвыми призраками, которые иногда запускались глубокой ночью. PEP 3147 был признан диктатором достойным и во времена 3.2.

Начиная с версии 3.2, Python хранит файлы PYC модуля в __pycache__ в каталоге модуля. Каждый файл PYC содержит имя и версию интерпретатора, например, __pycache__/foo.cpython-33.pyc. У вас также может быть __pycache__/foo.cpython-32.pyc, скомпилированный более ранней версией Python. Происходит правильная магия: используется правильный вариант и перекомпилируется, если он не синхронизирован с исходным кодом. Во время выполнения найдите в модуле mymodule.__cached__ имя файла pyc и проанализируйте его с помощью imp.get_tag(). См. раздел "Что нового" для получения дополнительной информации.

TL; DR - просто работает в Python 3.2 и выше. Плохие хаки заменяют предыдущие версии.

PEP 3147 - это только частичное решение. Каталоги __pycache__ все еще загромождают исходный код. Основное раздражение для меня с pycs - это каталоги, которые остались восстановленными после svn switch или чего-то подобного.

Suor 25.07.2013 07:30

Похоже на эстетическую проблему: кешированный .pyc будет использоваться только для точных совпадений меток времени; возможно из файла cmp.filecmp (shallow = True). Хотя это не красиво, дополнительные кеши использовать не следует.

Charles Merriam 03.10.2013 05:11

Пожалуйста, скажите, что, как и большинство вещей в 3.2, это также было включено в 2.7?

ArtOfWarfare 08.04.2015 23:07

Черт побери - просто запустил предложенный тест в PEP 3147 и получил ответ False. Это тест: import imp; hasattr(imp, 'get_tag').

ArtOfWarfare 08.04.2015 23:24

В частности, похоже, что PEP был завершен после того, как первая бета-версия 2.7 уже была выпущена. Тем не менее ... может, есть надежда? Они сделали бэкпорт модуля pip в 2.7.9 ... может быть, они смогут сделать бэкпорт в 2.7.11?

ArtOfWarfare 09.04.2015 16:30

@ArtOfWarfare Или, может быть, мы уже можем отказаться от python2! :-D

binki 17.02.2016 19:59

@binki - Нет Fabric в Python 3. Кроме того, почти каждая ОС по-прежнему поставляется с Python 2. Это две основные причины, по которым я все еще застрял на 2.7.

ArtOfWarfare 17.02.2016 20:01
Когда возникло новое царство, представители старого царства возжелали сокровищ новой земли. Многие набеги на декораторы классов, целочисленное деление и функции печати завершились победой. Только когда фермеры начали привозить телеги с верхним слоем почвы, старые решили мигрировать.
Charles Merriam 17.01.2017 21:07

@CharlesMerriam Из любопытства, к чему относится аллегория верхнего слоя почвы?

syockit 23.12.2020 14:43

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

Charles Merriam 30.12.2020 01:06

И только почти десять лет спустя Python 3.8, наконец, обеспечивает поддержку хранения байт-кода в отдельном дереве параллельной файловой системы, задав переменную среды PYTHONPYCACHEPREFIX или используя аргумент -X pycache_prefix=PATH (официальный документ здесь).

Для Python 3.8 или выше:

Параметр PYTHONPYCACHEPREFIX (также доступный как -ИКСpycache_prefix) настраивает неявный кэш байт-кода для использования отдельного дерева файловой системы, а не подкаталогов __pycache__ по умолчанию в каждом исходном каталоге.

Местоположение кэша указано в sys.pycache_prefix (None указывает местоположение по умолчанию в подкаталогах __pycache__).

Другие вопросы по теме