Мне дали понять, что Python - это интерпретируемый язык ...
Однако, когда я смотрю на свой исходный код Python, я вижу .pyc
файлы, которые Windows определяет как «Скомпилированные файлы Python».
Откуда они приходят?
python
compiled
interpreted-language
pyc
froadie
источник
источник
java
иjavac
.Ответы:
Они содержат байт-код , который является исходным кодом для интерпретатора Python. Этот код затем выполняется виртуальной машиной Python.
Документация Python объясняет определение следующим образом:
источник
Этот популярный мем некорректен, или, скорее, построен на неправильном понимании (естественного) уровня языка: похожая ошибка - сказать «Библия - книга в твердом переплете». Позвольте мне объяснить это сравнение ...
«Библия» - это «книга» в том смысле, что она представляет собой класс (реальных физических объектов, идентифицированных как) книг; Предполагается, что книги, обозначенные как «копии Библии», имеют что-то общее (содержание, хотя даже они могут быть на разных языках, с разными приемлемыми переводами, уровнями сносок и другими аннотациями), однако эти книги вполне допустимо отличаться множеством аспектов, которые не считаются фундаментальными - вид переплета, цвет переплета, шрифт (ы), используемые при печати, иллюстрации, если таковые имеются, широкие поля для записи или нет, числа и виды встроенных закладок , и так далее и тому подобное.
Вполне возможно, что типичная печать Библии действительно была бы в переплете в твердом переплете - в конце концов, это книга, которую обычно нужно читать снова и снова, делать закладки в нескольких местах, пролистывать в поисках данных указателей на главы и стихи и т. д., и т. д., и хорошее связывание в твердом переплете может продлить срок действия данной копии при таком использовании. Однако это обычные (практические) вопросы, которые нельзя использовать для определения того, является ли данный фактический объект книги копией Библии или нет: печатные издания в мягкой обложке вполне возможны!
Точно так же, Python является «языком» в смысле определения класса языковых реализаций, которые все должны быть похожи в некоторых фундаментальных отношениях (синтаксис, большинство семантик, за исключением тех частей, где им явно разрешено различаться), но полностью разрешено различаться практически во всех деталях «реализации» - включая то, как они работают с исходными файлами, которые им предоставляются, компилируют ли они исходные тексты в некоторые формы более низкого уровня (и, если да, то в какую форму - и сохраняют ли они такие скомпилированные формы, на диск или в другое место), как они выполняют указанные формы и т. д.
Классическая реализация, CPython, часто для краткости называется просто «Python» - но это всего лишь одна из нескольких реализаций производственного качества, наряду с Microsoft IronPython (который компилируется в коды CLR, т. Е. «.NET»), Jython (который компилируется в коды JVM), PyPy (который написан на самом Python и может компилироваться в огромное разнообразие «внутренних» форм, включая машинный язык, генерируемый «точно в срок»). Все они - Python (== "реализации языка Python"), точно так же, как многие поверхностно разные книжные объекты могут быть Библиями (== "копии Библии").
Если вы особенно заинтересованы в CPython: он компилирует исходные файлы в специфичную для Python форму нижнего уровня (известную как «байт-код»), делает это автоматически при необходимости (когда нет файла байт-кода, соответствующего исходному файлу, или файл байт-кода старше исходного или скомпилирован другой версией Python), обычно сохраняет файлы байт-кода на диск (чтобы не перекомпилировать их в будущем). OTOH IronPython обычно компилируется в коды CLR (сохраняя их на диск или нет, в зависимости от) и Jython в коды JVM (сохраняя их на диск или нет - он будет использовать
.class
расширение, если сохранит их).Эти формы более низкого уровня затем выполняются соответствующими «виртуальными машинами», также известными как «интерпретаторы» - виртуальная машина CPython, среда выполнения .Net, виртуальная машина Java (также известная как JVM), в зависимости от ситуации.
Таким образом, в этом смысле (что делают типичные реализации), Python является «интерпретируемым языком» тогда и только тогда, когда есть C # и Java: у всех них есть типичная стратегия реализации, которая сначала создает байт-код, а затем выполняет его через VM / интерпретатор. ,
Скорее всего, основное внимание уделяется тому, насколько «тяжелым», медленным и запоминающимся является процесс компиляции. CPython предназначен для компиляции настолько быстро, насколько это возможно, настолько легко, насколько это возможно, с минимально возможной церемонией - компилятор выполняет очень мало проверки и оптимизации ошибок, поэтому он может работать быстро и с небольшими объемами памяти, что, в свою очередь, позволяет ему запускаться автоматически и прозрачно при необходимости, даже если пользователю не нужно знать, что в большинстве случаев происходит компиляция. Java и C # обычно принимают больше работы во время компиляции (и поэтому не выполняют автоматическую компиляцию), чтобы более тщательно проверять ошибки и выполнять больше оптимизаций. Это континуум серых шкал, а не черная или белая ситуация,
источник
Там нет такой вещи, как интерпретируемый язык. Независимо от того, используется ли интерпретатор или компилятор, это особенность реализации и не имеет абсолютно никакого отношения к языку.
Каждый язык может быть реализован либо интерпретатором, либо компилятором. Подавляющее большинство языков имеют как минимум одну реализацию каждого типа. (Например, существуют интерпретаторы для C и C ++, а также есть компиляторы для JavaScript, PHP, Perl, Python и Ruby.) Кроме того, большинство современных реализаций языка фактически комбинируют как интерпретатор, так и компилятор (или даже несколько компиляторов).
Язык - это просто набор абстрактных математических правил. Интерпретатор - это одна из нескольких конкретных стратегий реализации языка. Эти двое живут на совершенно разных уровнях абстракции. Если бы английский был типизированным языком, термин «интерпретируемый язык» был бы ошибкой типа. Утверждение «Python - это интерпретируемый язык» - это не просто ложь (поскольку ложь подразумевает, что это утверждение даже имеет смысл, даже если оно неверно), оно просто не имеет смысла , поскольку язык никогда не может быть определен как «интерпретированы.»
В частности, если вы посмотрите на существующие в настоящее время реализации Python, это стратегии реализации, которые они используют:
Вы можете заметить, что у каждой из реализаций в этом списке (плюс некоторые другие, которые я не упомянул, например, tinypy, Shedskin или Psyco) есть компилятор. На самом деле, насколько я знаю, в настоящее время нет реализации Python, которая является чисто интерпретируемой, такой реализации не планируется и такой реализации никогда не было.
Термин «интерпретируемый язык» не только не имеет смысла, даже если вы интерпретируете его как «язык с интерпретируемой реализацией», он явно не соответствует действительности. Кто бы вам ни говорил, очевидно, не знает, о чем говорит.
В частности,
.pyc
файлы, которые вы видите, являются кэшированными файлами байт-кода, созданными CPython, Stackless Python или Unladen Swallow.источник
Они создаются интерпретатором Python при
.py
импорте файла и содержат «скомпилированный байт-код» импортированного модуля / программы, идея в том, что «перевод» из исходного кода в байт-код (который необходимо выполнить только один раз) может быть пропущен при последующихimport
s, если.pyc
он новее соответствующего.py
файла, что немного ускоряет запуск. Но это все еще интерпретируется.источник
Чтобы ускорить загрузку модулей, Python кэширует скомпилированное содержимое модулей в .pyc.
CPython компилирует свой исходный код в «байтовый код» и по соображениям производительности кэширует этот байтовый код в файловой системе всякий раз, когда в исходном файле есть изменения. Это значительно ускоряет загрузку модулей Python, потому что этап компиляции можно обойти. Если исходный файл - foo.py, CPython кэширует байт-код в файле foo.pyc рядом с исходным кодом.
В python3 механизм импорта Python расширен для записи и поиска файлов кэша байтового кода в одном каталоге внутри каждого каталога пакета Python. Этот каталог будет называться __pycache__.
Вот блок-схема, описывающая, как загружаются модули:
За дополнительной информацией:
ref: PEP3147
ref: «скомпилированные» файлы Python
источник
ЭТО ДЛЯ НАЧИНАЮЩИХ,
Python автоматически компилирует ваш скрипт в скомпилированный код, так называемый байтовый код, перед его запуском.
Запуск сценария не считается импортом, и .pyc не будет создан.
Например, если у вас есть файл сценария abc.py , который импортирует другой модуль xyz.py , при запуске abc.py , xyz.pyc будет создан , так как хуг импортируется, но не abc.pyc файл не будет создан , поскольку аЬс. py не импортируется.
Если вам необходимо создать .pyc файл для модуля , который не импортируется, вы можете использовать
py_compile
иcompileall
модули.py_compile
Модуль может вручную компилировать любой модуль. Одним из способов является использованиеpy_compile.compile
функции в этом модуле в интерактивном режиме:Это запишет .pyc в то же место, что и abc.py (вы можете переопределить его с помощью необязательного параметра
cfile
).Вы также можете автоматически скомпилировать все файлы в каталоге или каталогах, используя модуль compileall.
Если имя каталога (текущий каталог в этом примере) опущено, модуль компилирует все найденное на
sys.path
источник
Python (по крайней мере, самая распространенная его реализация) следует схеме компиляции исходного кода в байтовые коды, а затем интерпретирует байтовые коды на виртуальной машине. Это означает (опять же, самая распространенная реализация) не является ни чистым интерпретатором, ни чистым компилятором.
Другая сторона этого, однако, в том, что процесс компиляции в основном скрыт - файлы .pyc в основном обрабатываются как кеш; они ускоряют процесс, но обычно вам не нужно о них вообще знать. Он автоматически делает недействительными и перезагружает их (перекомпилирует исходный код), когда это необходимо, на основании отметок времени / даты файла.
Единственный раз, когда я видел проблему с этим, это когда скомпилированный файл байт-кода каким-то образом получал временную метку в будущем, что означало, что он всегда выглядел новее исходного файла. Поскольку он выглядел более новым, исходный файл никогда не перекомпилировался, поэтому независимо от того, какие изменения вы внесли, они были проигнорированы ...
источник
Файл * .py Python - это просто текстовый файл, в котором вы пишете несколько строк кода. Когда вы пытаетесь выполнить этот файл, используя «python filename.py»
Эта команда вызывает виртуальную машину Python. Виртуальная машина Python имеет 2 компонента: «компилятор» и «интерпретатор». Интерпретатор не может напрямую читать текст в файле * .py, поэтому этот текст сначала преобразуется в байтовый код, предназначенный для PVM (не аппаратного, а PVM) . PVM выполняет этот байт-код. Файл * .pyc также генерируется, как часть его запуска, который выполняет операцию импорта для файла в оболочке или в каком-либо другом файле.
Если этот * .pyc-файл уже создан, то каждый раз, когда вы запускаете / запускаете ваш * .py-файл, система напрямую загружает ваш * .pyc-файл, который не требует компиляции (это сэкономит вам некоторые машинные циклы процессора).
После создания файла * .pyc файл * .py не требуется, если вы его не редактируете.
источник
Код Python проходит 2 этапа. Первый шаг компилирует код в файлы .pyc, который на самом деле является байт-кодом. Затем этот файл .pyc (байт-код) интерпретируется с использованием интерпретатора CPython. Пожалуйста, обратитесь к этой ссылке. Здесь процесс компиляции и выполнения кода объясняется в простых терминах.
источник