Что такое компилятор python
Создание компилятора на Python
1. Введение
1.1 Цель
При проектировании какого-либо компилятора или интерпретатора в качестве инструмента, как правило, выбирают язык C. А что если планируется создать «небольшой язык программирования» , просто так, забавы ради (или, может быть, для более серьёзного применения)? Чего беспокоиться, если вы обладаете достаточно мощным инструментом — интерпретатором Python!
1.2 Инструменты
В рабочий каталог нужно переписать модули lex.py и yacc.py. Само собой, потребуется и Python версии 2.1 или выше.
2. Первый шаг
Перед тем, как углубиться в детали реализации, пройдемся по основным терминам и понятиям.
2.1 Лексемы
Что такое лексемы? Лексемы — это символы, подобные +, -, * или /, или это слова, такие как begin, end, if или while, которые могут выступать в качестве операндов в выражениях, зарезервированных или ключевых слов и т.п. Лексемы должны быть определены как регулярные выражения.
2.2 Определение языка программирования
Поскольку пишется компилятор для нашего конкретного языка программирования, то следует начать с определения этого языка, записав для него набор грамматических правил. Например, если предполагается введение в язык конструкции ‘if-then-else-endif’, то правило достаточно просто можно записать так:
if_statement : IF LPAREN statement RPAREN multiple-statements ELSE multiple-statements ENDIF
где (1) IF, LPAREN, RPAREN, ELSE и ENDIF — лексемы для синтаксических единиц if , ( , ) , else и endif соответственно. (2) ‘statement’ и ‘multiple-statements’ — различные конструкции, для которых должны быть определены свои правила.
2.3 Грамматический разбор
Говоря простыми словами, грамматический разбор (в просторечие — парсинг, от английского to parse, не путать с пирсингом — прим. ред. 🙂 есть проверка соответствия исходного текста программы заданному набору правил. Существуют различные методы разбора, но нам нет нужды вдаваться в детали. Вам достаточно лишь знать, что, имея набор правил (см. пример выше), синтаксический анализатор производит разбор текста программы в соответствии с этим набором.
3. Реализация
Итак, приступим к созданию компилятора. Процесс компиляции делится на несколько этапов.
- Выделение лексем
- Грамматический разбор
- Выполнение действий, определяемых семантикой языка.
- Создание промежуточного кода.
- Оптимизация
- Создание результирующего кода.
3.1 Набор правил
Как уже упоминалось, сначала необходимо определить язык программирования, для которого реализуется компилятор. Определитесь, какой набор конструкций и операторов вы хотите предоставить. Такие конструкции, как ‘while’, ‘if’, ‘ assignment statements’ (операция присваивания) и пр. обычно имеются в большинстве языков программирования, так же как и арифметические операторы, такие как +, -, *, / и пр. Затем необходимо создать набор грамматических правил для вашего языка программирования. Набор правил для поддержки операции присваивания приводится ниже.
assign_statement : VAR EQUALS statement statement : statement ADDOP term | statement SUBOP term | term term : term MULOP factor | term DIVOP factor | factor factor : VAR | NUM | LPAREN statement RPAREN
Здесь и далее мы будем придерживаться следующих соглашений о написании лексем и правил. Лексемы мы будем записывать в верхнем регистре (NUM, VAR, EQUALS, ADDOP, SUBOP, MULOP, DIVOP, LPAREN, RPAREN), а правила (assign_statement, statement, term, factor) — в нижнем.
3.2 Определение лексем и их анализ
import lex # Список лексем. Обязателен. tokens = ( 'NUM', 'VAR', 'EQUALS', 'ADDOP', 'SUBOP', 'MULOP', 'DIVOP', 'LPAREN', 'RPAREN' ) # Регулярные выражения для выделения лексем. t_VAR = r'[a-zA-Z_][\w_]*' t_EQUALS = r'=' t_ADDOP = r'\+' t_SUBOP = r'-' t_MULOP = r'\*' t_DIVOP = r'/' t_LPAREN = r'\(' t_RPAREN = r'\)' # Регулярное выражение, требующее дополнительных действий. def t_NUM(t) : r'\d+' try: t.value = int(t.value) except ValueError: print "Строка %d: Число %s слишком велико!" % (t.lineno, t.value) t.value = 0 return t # Правило трассировки номеров строк. def t_newline(t): r'\n+' t.lineno += len(t.value) # Строка, содержащая игнорируемые символы (пробелы и символы табуляции). t_ignore = ' \t' # Правило обработки ошибок def t_error(t): print "Недопустимый символ '%s'" % t.value[0] t.skip(1) # Создать анализатор lex.lex() # Получить данные со стандартного ввода data = raw_input() lex.input(data) # Выделение лексем while 1 : tok = lex.token() if not tok : break print tok
Если вы хотите использовать зарезервированные слова, то, как правило, достаточно добавить соответствующее имя (идентификатор) и создать функцию, реализующую действие зарезервированного слова, как показано ниже:
reserved = < 'if' : 'IF', 'then' : 'THEN', 'else' : 'ELSE', 'while' : 'WHILE', . >def t_VAR(t): r'[a-zA-Z_][\w_]*' t.type = reserved.get(t.value,'ID') # Проверка на зарезервированное слово return t
3.3 Грамматический разбор
# Yacc example import yacc # Получить таблицу лексем от лексического анализатора, # который был создан нами ранее # Для этого. from ourlex import tokens __var_names = <> def p_assign_statement(t) : 'assign_statement : VAR EQUALS statement' __var_names[t[1]] = t[3] def p_statement_plus(t) : 'statement : statement ADDOP term' t[0] = t[1] + t[3] def p_statement_minus(t) : 'statement : statement SUBOP term' t[0] = t[1] - t[3] def p_statement_term(t) : 'statement : term' t[0] = t[1] def p_term_times(t) : 'term : term MULOP factor' t[0] = t[1] * t[3] def p_term_div(t) : 'term : term DIVOP factor' t[0] = t[1] / t[3] def p_term_factor(t) : 'term : factor' t[0] = t[1] def p_factor_num(t) : 'factor : NUM' t[0] = t[1] def p_factor_var(t) : 'factor : VAR' if __var_names.has_key(t[1]) : t[0] = __var_names[t[1]] else : print "Имя переменной", t[1], " в строке ", t.lineno(1), "не определено." def p_factor_expr(t): 'factor : LPAREN statement RPAREN' t[0] = t[2] # Обработка синтаксических ошибок def p_error(t): print "Синтаксическая ошибка!" # Создать грамматический анализатор yacc.yacc() while 1: try: s = raw_input('enter > ') except EOFError: break if not s: continue yacc.parse(s)
Здесь каждая функция принимает единственный аргумент t — массив (на самом деле удобный Python’овый не-модифицируемый «массивосписок» — tuple. прим. ред.), содержащий грамматические элементы:
def p_statement_plus(t): 'statement : statement ADDOP term' # ^ ^ ^ ^ # t[0] t[1] t[2] t[3] t[0] = t[1] + t[3]
3.4 Семантика
Семантика определяет последовательность действий, которые должен выполнить грамматический анализатор, когда ему удается свести входной поток до одного конкретного правила. В нашем примере семантика соответствует программе-интерпретатору. В случае простого компилятора, результатом работы может оказаться соответствующий правилу ассемблерный код.
Предположим, что в результате работы компилятора должен получаться код на языке ассемблера для процессора 8086. Примем за правило, что регистр ‘bx’ используется для хранения промежуточных результатов. Встретив очередной операнд, необходимо содержимое регистра ‘ax’ переписать в регистр ‘bx’, после чего в регистр ‘ax’ занести новый операнд. Таким образом, последний встреченный операнд (или результат операции) всегда будет содержаться в регистре ‘ax’.
def p_factor_num(t) : 'factor : NUM' __output_fp.write("\tmov bx,ax\n"%f) # bx
где, '__output_fp' -- дескриптор результирующего файла.
После того, как операнды подготовлены к выполнению операции (унарной или бинарной), мы можем описать семантику операции, например сложения:
def p_statement_plus(t) : 'statement : statement ADDOP term' __output_fp.write("\tadd ax,bx\n") # ax
Аналогичным образом, встретив объявление переменной, можно предусмотреть выбрать регистр процессора для ее хранения (локальные переменные предпочтительнее размещать на стеке), и запомнить выделенный регистр в словаре. Всякий раз, когда встречается ссылка на имя переменной, используя имя переменной в качестве ключа можно найти имя соответствующего регистра.
3.5 Оптимизация
Если говорить о компиляторе языка C, то ассемблерный код получается сложнее, чем описано выше. В действительности компилятор производит сначала некоторый промежуточный код, затем этот код оптимизируется и, наконец, создается окончательный вариант ассемблерного кода.
Тема оптимизации кода слишком обширна, чтобы обсуждать ее здесь, поэтому остановимся лишь на самом простом методе оптимизации - локальная оптимизация [peephole optimization]. Простейший способ выполнения локальной оптимизации -- написать участок кода на языке ассемблера вручную и сравнить его с кодом, создаваемым вашим компилятором.
Например, если в имеющемся наборе отсутствует инструкция умножения, то вы можете заставить компилятор производить код, выполняющий умножение, через последовательность сложений. В качестве оптимизации можно предложить проверять величину операндов, и если один из них равен 1, то в качестве результата можно сразу принять второй операнд, минуя цикл сложений. Далее, поскольку величина множителя (количество значимых бит прим. перев.) определяет количество итераций, в качестве множителя можно назначать меньший из операндов.
Еще один пример локальной оптимизации -- оптимизация безусловных переходов:
jmp .L1 . . . . . .L1 jmp .L2 . . . . . .L2 add ax,bx
В этом случае, число выполняемых инструкций безусловного перехода можно сократить, изменив первую команду jump :
jmp .L2 . . . . . .L1 jmp .L2 . . . . . .L2 add ax,bx
Существуют различные алгоритмы оптимизации. Методы, описанные выше, являются лишь первым маленьким шагом в направлении оптимизации по времени исполнения и размеру создаваемого кода.
4. Что дальше?
Примеры, приведенные выше, не являются полнофункциональным компилятором. Для их завершения требуется реализовать гораздо большее число привычных конструкций. Эти примеры можно рассматривать лишь как иллюстрацию написания соответствующих этим привычным конструкциям правил, регулярных выражений (для выделения лексем), функций грамматического разбора и функций реализации семантики языка.
Dinil Divakaran
Я -- студент последнего года по специальности "Информатика" [computer science] в колледже GEC Thrissur в Керале, Индия.
Copyright (C) 2002, Dinil Divakaran.
Компиляция Python

Предположим, вы разработали приложение или библиотеку на Python и уже готовитесь передать его / её заказчику. И в этот момент возникают вопросы, о которых многие даже не задумываются.
Во-первых, так может оказаться, что вы разработали супер крутой алгоритм, которого ни у кого нет, и показывать его хочется только избранным.
Во-вторых, возникает вопрос окружения - хочется быть уверенным, что заказчик справится с установкой правильной версии Python и всех вспомогательных библиотек, но это не всегда простая задача. Было бы удобно упаковать приложение в автономный исполняемый файл.
И, наконец, хочется, чтобы конечное приложение работало быстрее, чем в среде разработки.
И вот тут настало время скомпилировать Python-код. Меня зовут Руслан, я старший разработчик компании «Цифровое проектирование». Сегодня я расскажу, как выбрать тот самый компилятор из множества доступных.
AOT/JIT
Компиляция – это сборка программы, включающая: трансляцию всех модулей программы, написанных на языке программирования высокого уровня, в эквивалентные программные модули на низкоуровневом языке, близком к машинному коду, или на машинном языке и сборку исполняемой программы. Существует два вида компиляции:
- AOT-компиляция (ahead-of-time) – компиляция перед исполнением программы. Т.е. программа компилируется один раз, в результате компиляции получается исполняемый файл.
- JIT-компиляция (just-in-time) – компиляция во время исполнения программы. Т.е. программа (а точнее, блоки программы) компилируется много раз - при каждом запуске.
Бенчмарк
Так как одной из целей является ускорение, необходимо оценить, насколько быстро работает скомпилированный код. В качестве бенчмарка будем использовать pyperfomance. К сожалению, pyperfomance не подошел для Cython и Pythran, потому что не позволяет визуализировать все возможности языка. Ускорения для Cython без модификации кода получить не удалось, а Pythran не умеет в пользовательские классы. Для них воспользуемся вычислением числа пи:
def approximate_pi(n): step = 1.0 / n result = 0 for i in range(n): x = (i + 0.5) * step result += 4.0 / (1.0 + x * x) return step * result
Эксперименты будем проводить на процессоре Intel Core i7 10510U. На CPython 3.9.7 время вычисления числа пи до 100.000.000 знака заняло 5.82 секунды.
AOT-компиляция Python
PyInstaller
PyInstaller упаковывает приложения Python в автономные исполняемые файлы в Windows, GNU / Linux, Mac OS X, FreeBSD, Solaris и AIX.
Устанавливается через pip:
pip install pyinstaller
После установки для создания исполняемого файла достаточно выполнить команду:
В результате будет создано:
- *.spec – файл спецификации (используется для ускорения будущих сборок приложения, связи файлов данных с приложением, для включения .dll и .so файлов, добавление в исполняемый файл параметров runtime-а Python);
- build/ – директория с метаданными для сборки исполняемого файла;
- dist/ – директория, содержащая все зависимости и исполняемый файл.
Сборку приложения можно настроить с помощью параметров командной строки:
- --name – изменение имени исполняемого файла (по умолчанию, такое же, как у сценария);
- --onefile – создание только исполняемого файла (по умолчанию, папка с зависимостями и исполняемый файл);
- --hidden-import – перечисление импортов, которые PyInstaller не смог обнаружить автоматически;
- --add-data – добавление в сборку файлов данных;
- --add-binary – добавление в сборку бинарных файлов;
- --exclude-module – исключение модулей из исполняемого файла;
- --key – ключ шифрования AES256. Да, приложение не будет содержать исходного кода, но его можно декомпилировать, например, так: Pyinstaller Extractor (.exe → .pyc) и uncompile6 (.pyc → .py). Для скрытия исходного кода можно обфусцировать байт-код Python с помощью шифрования.
У PyInstaller есть ограничения. Он работает с Python 3.5–3.9. Поддерживает создание исполняемых файлов для разных операционных систем, но не умеет выполнять кросскомпиляцию, т. е. необходимо генерировать исполняемый файл для каждой ОС отдельно. Более того, исполняемый файл зависит от пользовательского glibc, т. е. необходимо генерировать исполняемый файл для самой старой версии каждой ОС.
PyInstaller знает о многих Python-пакетах и умеет их учитывать при сборке исполняемого файла. Но не о всех. Например, фреймворк uvicorn практически весь нужно явно импортировать в файл, к которому будет применена команда pyinstaller. Полный список поддерживаемых из коробки пакетов можно посмотреть здесь.
Cython
Cython - это оптимизирующий статический компилятор как для языка программирования Python, так и для расширенного языка программирования Cython. С его помощью можно код на Python транслировать в С и затем скомпилировать в бинарник, совместимый с CPython. Компиляцию придется делать под все операционные системы и архитектуры процессора.
Ставится Cython через pip:
pip install Cython
Рассмотрим его работу на примере с вычислением числа пи:
def approximate_pi(int n): cdef float step cdef float result cdef float x step = 1.0 / n result = 0.0 for i in range(n): x = (i + 0.5) * step result += 4.0 / (1.0 + x * x) return step * result
А что делать, если в нашем проекте несколько файлов, которые нужно скомпилировать? Тогда нужно использовать так называемый сценарий сборки. С его помощью можно модернизировать сборку в зависимости от операционной системы, указывать несколько файлов, которые необходимо скомпилировать, и многое другое.
Создадим файл build.py:
from distutils.core import setup from Cython.Build import cythonize setup( ext_modules=cythonize("bench_cython.pyx"), )
Запустим: python build.py build_ext –-inplace
В результате будет сгенерирован .so/.dll файл.
Nuitka
Nuitka способна упаковывать приложения Python в автономные исполняемые файлы, а также транслировать Python-код в С для его последующей компиляции. Работает с разными версиями Python (2.6, 2.7, 3.3 - 3.9).
Ставится через pip:
pip install nuitka
Для генерации исполняемого файла достаточно выполнить команду:
python -m nuitka --follow-import some_program.py
Для компиляции модуля:
python -m nuitka --module some_module.py
Для компиляции пакета:
python -m nuitka --module some_package --include-package = some_package
Pythran
Pythran – статический компилятор Python, позиционирующий себя как ориентированный на научные вычисления и использующий преимущества многоядерных процессоров и блоков инструкций SIMD. Он транслирует Python-код, аннотированный описаниями интерфейса, в C++. До версии 0.9.5 (включительно) Pythran поддерживал Python 3 и Python 2.7. Последние версии поддерживают только Python 3.
pip install pythran
Генерируем бинарный файл .so:
Pythran по умолчанию не умеет в пользовательские классы, поэтому при попытке их компиляции будет выброшена ошибка:
Top level statements can only be assignments, strings,functions, comments, or imports
Добавим комментарий аннотации функции:
#pythran export approximate_pi(int) def approximate_pi(n): step = 1.0 / n result = 0 for i in range(n): x = (i + 0.5) * step result += 4.0 / (1.0 + x * x) return step * result
Скомпилируем и бенчмарк выдает 0,00007 секунды.
cx-Freeze
cx-Freeze – это набор скриптов и модулей преобразования скриптов Python в исполняемые файлы. cx_Freeze - кроссплатформенный. Он поддерживает Python 3.5.2 и выше.
Ставится с помощью pip:
pip install cx_Freeze
Для генерации исполняемого файла достаточно выполнить команду:
Сборку можно настроить с помощью параметров командной строки:
- -h, --help - справка;
- -O - оптимизировать сгенерированный байт-код согласно PYTHONOPTIMIZE;
- -c, --compress - сжать байт-код в zip-файлах;
- -s, --silent - выводить только предупреждения и ошибки;
- --target-dir=DIR, --install-dir=DIR - каталог, в который следует поместить целевой файл и все зависимые файлы.
Также возможно использование сценария сборки, например, так:
import sys from cx_Freeze import setup, Executable # Dependencies are automatically detected, but it might need fine tuning. build_exe_options = # GUI applications require a different base on Windows (the default is for a # console application). base = None if sys.platform == "win32": base = "Win32GUI" setup( name = "guifoo", version = "0.1", description = "My GUI application!", options = , executables = [Executable("guifoo.py", base=base)])
Сборка исполняемого файла:
python setup.py build
JIT-компиляция Python
JIT-компиляция не позволяет скрывать исходники или создавать автономный исполняемый файл, но дает возможность значительно ускорить выполнение программы.
PyPy
PyPy - интерпретатор языка программирования Python 2.7 и Python 3.7. Он написан на RPython и содержит:
- компилятор байт-кода, отвечающий за создание объектов кода Python из исходного кода пользовательского приложения;
- оценщик байт-кода, ответственный за интерпретацию объектов кода Python;
- стандартное объектное пространство, отвечающее за создание и управление объектами Python, видимыми приложением.
PyPy поддерживает сотни библиотек Python, включая NumPy.
Основные особенности (сравнение с CPython):
- Скорость. При выполнении длительно выполняющихся программ, когда значительная часть времени тратится на выполнение кода Python, PyPy может значительно ускорить ваш код.
- Использование памяти. Программы Python, требующие много памяти (несколько сотен Мб или более), могут занимать меньше места, чем в CPython. Однако это не всегда так, поскольку зависит от множества деталей. Также базовый уровень потребления оперативной памяти выше, чем у CPython.
Скачать PyPy можно с здесь. После скачивания PyPy готов к запуску после распаковки архива. Если необходимо сделать PyPy доступным для всей системы, достаточно поместить символическую ссылку на исполняемый файл pypy в /usr/local/bin. Также можно поставить с помощью pyenv.
PyPy работает на Mac, Linux (не все дистрибутивы) или Windows.
Для запуска кода с помощью PyPy вместо команды python3 (как c помощью CPython) достаточно воспользоваться командой pypy3:
Pyston
Pyston - это форк CPython 3.8.8 с дополнительной оптимизацией производительности. В настоящее время он поддерживает установку только из исходников. Или с помощью pyenv.
В Pyston поддерживаются все возможности CPython, в том числе C API для разработки расширений на языке Си. Среди основных отличий Pyston от CPython помимо общих оптимизаций выделяется использование DynASM JIT и inline-кэширования.
Заключение
Итак, мы рассмотрели 5 фреймворков AOT-компиляции Python. Для любителей аналитики, ниже приведена таблица со сравнительным анализом.
PyInstaller
Cython
Nuitka
Pythran
cx-Freeze
Генерация автономных исполняемых файлов
Компиляция python-модуля в исполняемый файл, совместимый с CPython
Как работает Python: интерпретатор, байт-код, PVM
Python — интерпретируемый язык программирования. Он не конвертирует свой код в машинный, который понимает железо (в отличие от С и С++). Вместо этого, Python-интерпретатор переводит код программы в байт-код, который запускается на виртуальной машине Python (PVM). Давайте рассмотрим подробнее, как это работает на примере самой популярной реализации интерпретатора — CPython.
Интерпретатор — это программа, которая конвертирует ваши инструкции, написанные на Python, в байт-код и выполняет их. По сути интерпретатор — это программный слой между вашим исходным кодом и железом.
Существует 2 типа интерпретаторов:
- Простой интерпретатор . Он берет одну инструкцию, транслирует и сразу выполняет ее, а затем берет следующую инструкцию.
- Интерпретатор компилирующего типа . Это система из компилятора и интерпретатора. Компилятор переводит исходный код программы в промежуточное представление (байт-код), а интерпретатор (виртуальная машина) выполняет этот байт-код.
- Интерпретатор компилирующего типа (благодаря этому достигается большее быстродействие выполнения программ).
- Считается эталонной реализацией языка Python.
- Написан на C.
- Исходный код CPython находится в открытом доступе.
- Его разработка ведётся группой разработчиков под руководством Гвидо ван Россума — создателя Python.
Кроме этого, у интерпретатора CPython есть особенность — он может работать в режиме диалога (REPL — read-eval-print loop). Интерпретатор считывает законченную конструкцию языка, выполняет её, печатает результаты и переходит к ожиданию ввода пользователем следующей конструкции.
Как CPython выполняет программы
Интерпретатор "Питона" выполняет любую программу поэтапно.
Этап #1. Инициализация
После запуска вашей программы, Python-интерпретатор читает код, проверяет форматирование и синтаксис. При обнаружении ошибки он незамедлительно останавливается и показывает сообщение об ошибке.
Помимо этого, происходит ряд подготовительных процессов:
- анализ аргументов командной строки;
- установка флагов программы;
- чтение переменных среды и т.д.
Этап #2. Компиляция
Интерпретатор транслирует (переводит) исходные инструкции вашей программы в байт-код (низкоуровневое, платформонезависимое представление исходного текста). Такая трансляция необходима в первую очередь для повышения скорости — байт-код выполняется в разы быстрее, чем исходные инструкции.
Если Python-интерпретатор обладает правом записи, он будет сохранять байт-код в виде файла с расширением .pyc . Если исходный текст программы не изменился с момента последней компиляции, при следующем запуске вашей программы, Python сразу загрузит файл .pyc , минуя этап компиляции (тем самым ускорит процесс запуска программы).
Этап #3. Выполнения
Как только байт-код скомпилирован, он отправляется на виртуальную машину Python (PVM). Здесь выполняется байт-код на PVM. Если во время этого выполнения возникает ошибка, то выполнение останавливается с сообщением об ошибке.
PVM является частью Python-интерпретатора. По сути это просто большой цикл, который выполняет перебор инструкций в байт-коде и выполняет соответствующие им операции.
Альтернативы CPython
CPython является стандартной реализацией, но существуют и другие реализации, созданные для специфических целей и задач.
Jython
Основная цель данный реализации — тесная интеграция с языком Java. Работает следующим образом:
- Java-классы выполняют компиляцию программного кода на языке Python в байт-код Java.
- Полученный байт-код запускается на виртуальной машине Java (JVM).
Jython позволить Python-программам управлять Java-приложениями. Во время выполнения такая программа ведет себя точно так же, как настоящая программа на языке Java.
IronPython
Предназначена для обеспечения интеграции Python-программ с C# приложениями на Microsoft .NET Framework или Mono. Принцип работы такой же, как и у Jython.
PyPy
PyPy — это интерпретатор Python, написанный на Python (если быть точнее, то на RPython).
Особенностью PyPy является использование трассирующего JIT-компилятора (just-in-time), который на лету транслирует некоторые элементы в машинный код. Благодаря этому, при выполнении некоторых операций PyPy обгоняет CPython в несколько раз. Но плата за такую производительность — более высокое потребление памяти.
Компиляторы и трансляторы кода Python

Компьютерная программа, переводящая код, написанный на одном языке программирования, в другой, называется транслятором, а из языка в машинный код — компилятором. Python возглавляет фракцию самых быстрорастущих языков программирования. Таким образом, нет недостатка в компиляторах и трансляторах для Python, которые могут удовлетворить различные потребности проекта.
Введение
В первую очередь, компиляторы — это программы, которые преобразуют исходный код, написанный на языке программирования высокого уровня, в язык программирования более низкого уровня, такой как машинный код, для создания исполняемой программы.
Хотя компилятор CPython является де-факто компилятором для Python, поскольку он относится к эталонной реализации Python, т.е. CPython, существует несколько других компиляторов Python, которые разработчики любят использовать.
Давайте рассмотрим 7 лучших компиляторов для Python.
Brython — реализация Python для браузера

Brython, отмеченный как «реализация Python 3 для веб-программирования на стороне клиента», является популярным компилятором, который преобразует код Python в код JavaScript.
Адаптированный к среде HTML5, Brython поставляется с интерфейсом для объектов и событий DOM. Brython — это сокращение от Browser Python. Он может похвастаться широким функционалом, начиная от создания простых элементов документа и перетаскивания до трехмерной навигации. Компилятор Python работает в Firefox намного лучше, чем в Google Chrome. Brython поддерживает не только все современные настольные браузеры, но и так же мобильные веб-браузеры. Компилятор Python поставляется с консолью JavaScript, которую можно использовать для оценки времени выполнения некоторой программы JS по сравнению с ее эквивалентом Python в редакторе. Согласно официальному блогу Пьера Квентеля, создателя и ведущего разработчика Brython, Brython намного быстрее Pypy.js и Skulpt. В некоторых случаях компилятор Python работает даже быстрее, чем эталонная реализация Python, то есть CPython. Brython поддерживает большую часть синтаксиса Python 3, например генераторы и импорт библиотек. Он также обеспечивает поддержку нескольких модулей, принадлежащих дистрибутиву CPython, и поставляется с библиотеками для взаимодействия с элементами и событиями DOM. Поддержка последних спецификаций HTML5 / CSS3 также доступна в Brython, а компилятор Python может использовать популярные CSS-фреймворки, такие, как BootStrap и LESS.
Nuitka — компилятор Python написанный на языке Python

Nuitka — это компилятор Python, написанный на языке Python.
Официальный сайт проекта: https://nuitka.net
Nuitka берет код Python и компилирует его в исходный код C / C++ или исполняемые файлы. Его можно использовать для разработки автономных программ, даже если на вашем компьютере не запущен Python.
Написанная полностью на Python, Nuitka позволяет использовать различные библиотеки Python и модули расширения.
Компилятор доступен для платформ FreeBSD, Linux, macOS X, NetBSD и Windows и находится под лицензией Apache License версии 2.0. Nuitka также доступна с Anaconda для тех, кто предпочитает ее для разработки проектов, связанных с наукой о данных и машинным обучением.
Платформа для разработки PyJS

Для тех, кто хочет писать код Python и выполнять его в веб-браузерах, PyJS — один из вариантов.
Официальный сайт проекта: http://pyjs.org
Компилятор PyJS переводит код Python в эквивалентный код JavaScript, чтобы он мог выполняться внутри веб-браузера. Важным аспектом PyJS является то, что он поставляется с фреймворком AJAX, который заполняет пробелы, оставшиеся между поддержкой JS и DOM, доступной для различных веб-браузеров. Чтобы сгенерировать эквивалентный код JS, PyJS использует абстрактное синтаксическое дерево Python.
Исходный код веб-приложения Python можно запустить как автономное настольное приложение (которое работает под Python) с помощью модуля PyJS Desktop. Интересно, что в некоторых системах Unix предустановлены версии PyJS и PyJS Desktop. Несмотря на различия между Python и JavaScript, большинство типов данных в двух популярных языках программирования идентичны.
При использовании PyJS некоторые типы данных Python преобразуются в настраиваемые объекты, например списки. PyJS — легкое приложение. Кроме того, он может использоваться непосредственно из веб-браузера и позволяет запускать программы из JS-консоли веб-браузера. Компилятор PyJS также предлагает поддержку во время выполнения.
Поскольку код Python можно встраивать в код JS, разработчики JS могут проектировать и разрабатывать приложения в чисто объектно-ориентированной парадигме с использованием PyJS.
Shed Skin — экспериментальный компилятор для Python

Еще один популярный компилятор Python — Shed Skin.
Он преобразует статически типизированную программу Python в эквивалентную программу на чистом C++. Статически типизированный означает, что используемые переменные должны относиться только к одному типу данных. Shed Skin не поддерживает некоторые общие функции, такие как использование вложенных функций и определение функций, которые принимают различное количество аргументов. Только некоторые стандартные функции библиотеки Python доступны для использования с Shed Skin. В качестве экспериментальной программы компилятора Shed Skin предлагает перевести статически типизированные программы Python в оптимизированный код C++ с несколькими ограничениями. Кроме того, Shed Skin не может масштабироваться более, чем на несколько тысяч строк кода. Если в вашем коде есть неподдерживаемый модуль Shed Skin, вы должны удалить его и добавить простой код для воспроизведения желаемой функциональности.
Несмотря на свой экспериментальный статус, Shed Skin может создавать автономные программы или модули расширения, которые можно импортировать и использовать в больших программах Python. Самым большим преимуществом использования Shed Skin является то, что он позволяет значительно повысить производительность. Это главным образом связано с тем, что компилятор Python переопределил встроенные типы данных Python в свой собственный набор классов, реализованный в эффективном коде C++.
Skulpt — полностью браузерная реализация Python

Написанный на JavaScript и доступный по лицензии MIT, Skulpt предлагает настоящую среду, в которой скомпилированный код выполняется в форме JS.
Официальный сайт проекта: https://skulpt.org
Поскольку Skulpt — это реализация Python в браузере, нет необходимости в дополнительной обработке, плагинах или поддержке на стороне сервера, необходимых для запуска Python в веб-браузере. Любой код Python, написанный в Skulpt, выполняется непосредственно в веб-браузере. Skulpt — хороший вариант для разработчиков, которые хотят создать веб-приложение, позволяющие пользователям запускать программы Python внутри веб-браузера, обеспечивая безопасность фоновых сервисов. Популярный компилятор Python также можно легко встроить в существующий блог или веб-страницу. Для индивидуальной интеграции в HTML можно добавить код Skulpt. Вы также можете научить Skulpt импортировать свои собственные модули для большего контроля. Хотя Skulpt переводит код Python в код JS, он не облегчает выполнение последнего.
Transcrypt — быстрый транслятор кода Python в JavaScript

Еще один популярный компилятор Python — Transcrypt. Он позволяет скомпилировать довольно обширное подмножество Python в компактный, читаемый и простой для отладки код JavaScript.
Компилятор Python следует упрощенному и мощному синтаксису, не требуя дополнительных расширений. Transcrypt прекомпилирует в быстрый, читаемый JS-код, который можно отлаживать из исходного кода Python с помощью исходных карт. Облегченный компилятор обеспечивает поддержку нарезки с помощью матрицы [i: j: k] и векторных операций с операторами +, -, * и /. Линтер, минификатор и валидатор статического типа встроены в Transcrypt. Таким образом, компилятор Python улучшает взаимодействие команды, работающей над полномасштабными проектами. Помимо беспрепятственного доступа к любой JS-библиотеке, Transcrypt также может работать поверх Node.js.
Благодаря поддержке иерархических модулей, локальных классов и множественного наследования Transcrypt может похвастаться гибкой и стабильной общей структурой.
WinPython — версия Python адаптированная для Windows

WinPython — это дистрибутив Python, специально созданный для операционной системы Windows.
Более ранние версии CPython не были оптимизированы под Windows и, как таковые, содержали много ошибок. WinPython был инкубирован как решение проблемы. Хотя нынешние версии CPython очень стабильны в операционной системе Windows, WinPython имеет несколько эксклюзивных функций. Поскольку WinPython является автономным дистрибутивом для Python, вам нужно только загрузить и распаковать его, чтобы начать работу. WinPython также поставляется с некоторыми из самых популярных библиотек Python для науки о данных и машинного обучения, таких как NumPy, Pandas и SciPy. Следовательно, вы можете сразу же работать с этими библиотеками Python.
WinPython поставляется с множеством встроенных функций, которые в большинстве случаев не требуются, например, компилятор C и C ++. Это может быть серьезным ограничением, поскольку нет возможности выбрать и загрузить только те функции, которые необходимы. Тем не менее, WinPython доступен в варианте нулевого пакета, который поставляется только с компилятором Python и не более того.
Заключение
На этом завершается данный список из семи лучших компиляторов Python. Поскольку каждый из них разработан с учетом конкретных требований, вы можете использовать их для удовлетворения различных потребностей. В программировании, чем больше программист знает, тем лучше.