Могу ли я запустить интерпретатор Python без создания скомпилированных файлов .pyc?






Насколько я знаю, python будет компилировать все модули, которые вы «импортируете». Однако python НЕ будет компилировать запуск сценария python с использованием: "python script.py" (однако он будет компилировать любые модули, импортируемые сценарием).
Настоящий вопрос: почему вы не хотите, чтобы Python компилировал модули? Вы, вероятно, могли бы автоматизировать способ их очистки, если они мешают.
Вы можете сделать каталоги, в которых существуют ваши модули, доступными только для чтения для пользователя, от имени которого работает интерпретатор Python.
Не думаю, что есть более элегантный вариант. PEP 304, похоже, был попыткой ввести простой вариант для этого, но, похоже, от него отказались.
Я полагаю, что, вероятно, вы пытаетесь решить какую-то другую проблему, для которой отключение .py [co] могло бы показаться обходным путем, но, вероятно, будет лучше вместо этого атаковать эту исходную проблему.
В 2.5 нет другого способа подавить это, кроме таких мер, как запрет пользователям права записи в каталог.
Однако в Python 2.6 и 3.0 в модуле sys может быть параметр, называемый «dont_write_bytecode», который может быть настроен для подавления этого. Это также можно установить, передав параметр «-B» или задав переменную среды «PYTHONDONTWRITEBYTECODE».
От «Что нового в Python 2.6 - изменения интерпретатора»:
Python can now be prevented from writing .pyc or .pyo files by supplying the -B switch to the Python interpreter, or by setting the PYTHONDONTWRITEBYTECODE environment variable before running the interpreter. This setting is available to Python programs as the
sys.dont_write_bytecodevariable, and Python code can change the value to modify the interpreter’s behaviour.
Обновление 2010-11-27: Python 3.2 решает проблему загромождения исходных папок файлами .pyc путем введения специальной подпапки __pycache__, см. Что нового в Python 3.2 - каталоги репозитория PYC.
По крайней мере, в OS X 10.8 с Python 2.7 переменная среды не действует.
Если вы встраиваете интерпретатор (в программу на C++), используйте «Py_DontWriteBytecodeFlag = 1;» в вашем исходном коде. Это глобальный int, объявленный в pydebug.h.
Переменная окружения отлично работает для меня в 2.7, я не знаю, какие проблемы возникают у других. Спасибо!
У меня тоже работал на OSX (10.8 и 10.10); @sorin правильно ли вы экспортировали переменную? export PYTHONDONTWRITEBYTECODE=1
Будет ли использование -B / PYTHONDONTWRITEBYTECODE замедлять выполнение / запуск кода Python?
Вы знаете, как сделать то же самое с pytest?
На самом деле есть способ сделать это в Python 2.3+, но это немного эзотерично. Не знаю, понимаете ли вы это, но вы можете сделать следующее:
$ unzip -l /tmp/example.zip
Archive: /tmp/example.zip
Length Date Time Name
-------- ---- ---- ----
8467 11-26-02 22:30 jwzthreading.py
-------- -------
8467 1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip') # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
По данным библиотеки zipimport:
Any files may be present in the ZIP archive, but only files .py and .py[co] are available for import. ZIP import of dynamic modules (.pyd, .so) is disallowed. Note that if an archive only contains .py files, Python will not attempt to modify the archive by adding the corresponding .pyc or .pyo file, meaning that if a ZIP archive doesn't contain .pyc files, importing may be rather slow.
Таким образом, все, что вам нужно сделать, это заархивировать файлы, добавить zip-файл в свой sys.path и затем импортировать их.
Если вы создаете это для UNIX, вы также можете подумать о том, чтобы упаковать свой скрипт, используя этот рецепт: исполняемый файл unix zip, но обратите внимание, что вам, возможно, придется настроить это, если вы планируете использовать stdin или читать что-либо из sys.args (это МОЖЕТ быть сделано без слишком много проблем).
По моему опыту, производительность из-за этого не сильно страдает, но вам следует дважды подумать, прежде чем импортировать таким образом любые очень большие модули.
import sys
sys.dont_write_bytecode = True
Я просто попробовал это, и он работает для импортированных модулей. В частности, после установки этой переменной все, что импортировано позже, не будет генерировать файлы pyc. Это восхитительно. Спасибо.
Вместо того, чтобы добавить это в родительский модуль, попробуйте добавить это в указанный скрипт. Это круто работает. Спасибо @te wilson
Добавьте это в свой site-packages/usercustomize.py, чтобы применить ко всем вашим скриптам. Для меня это каталог $HOME/.local/lib/python2.6/site-pacakges/usercustomize.py. Ср. docs.python.org/2/tutorial/…
можем ли мы добавить [sys.dont_write_bytecode = True] в файл settings.py для всех.
Мои пакеты сайтов были расположены по адресу: /usr/local/lib/python2.7/site-packages, и мне пришлось создать usercustomize.py
Или в одну строку: import sys; sys.dont_write_bytecode = True
Работает с Python 2.7.9 в Windows - так же, как @tea сказал выше.
sys.dont_write_bytecode = True не работает, по крайней мере, в python 2.7 в случае сценария с управляемой версией митипроцессинга.
У меня есть несколько тестовых примеров в тестовом наборе, и до того, как я запускал тестовый набор в Mac Terminal, вот так:
python LoginSuite.py
Выполняя команду таким образом, мой каталог заполнялся файлами .pyc. Я попробовал указанный ниже метод, и он решил проблему:
python -B LoginSuite.py
Этот метод работает, если вы импортируете тестовые наборы в набор тестов и запускаете набор из командной строки.
Вы можете установить sys.dont_write_bytecode = True в своем источнике, но это должно быть в первом загруженном файле python. Если вы запустите python somefile.py, вы не получите somefile.pyc.
Когда вы устанавливаете утилиту с использованием setup.py и entry_points=, вы должны указать sys.dont_write_bytecode в сценарии запуска. Таким образом, вы не можете полагаться на сценарий запуска «по умолчанию», созданный с помощью setuptools.
Если вы запускаете Python с файлом python в качестве аргумента, вы можете указать -B:
python -B somefile.py
somefile.pyc все равно не будет сгенерирован, но файлы .pyc для других импортированных файлов тоже не будут.
Если у вас есть утилита myutil, и вы не можете ее изменить, она не будет передавать -B интерпретатору python. Просто запустите его, установив переменную окружения PYTHONDONTWRITEBYTECODE:
PYTHONDONTWRITEBYTECODE=x myutil
Решение для ipython 6.2.1 using python 3.5.2 (протестировано на Ubuntu 16.04 и Windows 10):
Ipython не учитывает %env PYTHONDONTWRITEBYTECODE =1, если он установлен в интерпретаторе ipython или во время запуска в ~/.ipython/profile-default/startup/00-startup.ipy.
Вместо этого в ~.ipython/profile-default/startup/00-startup.py используйте следующее:
import sys
sys.dont_write_bytecode=True
Начиная с Python 3.8, вы можете использовать переменную среды PYTHONPYCACHEPREFIX для определения каталога кеша для Python.
Из документов Python:
If this is set, Python will write .pyc files in a mirror directory tree at this path, instead of in pycache directories within the source tree. This is equivalent to specifying the -X pycache_prefix=PATH option.
Пример
Если вы добавите следующую строку в свой ./profile в Linux:
export PYTHONPYCACHEPREFIX = "$HOME/.cache/cpython/"
Python не будет создавать надоедливые каталоги __pycache__ в каталоге вашего проекта, вместо этого он поместит их все в ~/.cache/cpython/.
Я часто обнаруживал, что есть устаревшие файлы с байт-кодом
.pyc. По какой-то причине, когда я меняю класс / модуль, файл.pycне обновляется. Поэтому, когда я импортирую его после изменения файла.py, он все равно будет использовать файл.pyc, что приведет к ошибкам.