← Назад к вопросам

Python компилируемый или интерпретируемый язык программирования

1.3 Junior🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Компилируемый или интерпретируемый язык?

Это распространённый вопрос на собеседованиях, и ответ может показаться парадоксальным: Python — это оба одновременно. Однозначного ответа нет, потому что различие между компиляцией и интерпретацией касается реализации, а не языка.

Коротко: Python — это язык, который обычно интерпретируется

Одноко технически Python сначала компилируется в байт-код, а затем интерпретируется виртуальной машиной Python (PVM).

Как на самом деле работает Python

Исходный код (.py)
         ↓
   [КОМПИЛЯТОР]
         ↓
Байт-код (.pyc)
         ↓
  [ИНТЕРПРЕТАТОР PVM]
         ↓
    Исполнение

Шаг 1: Компиляция

При первом импорте модуля Python компилирует исходный код в байт-код:

# mymodule.py
def calculate(x):
    return x * 2

result = calculate(5)

После первого импорта создаётся файл:

__pycache__/mymodule.cpython-39.pyc

В нём хранится байт-код — промежуточное представление:

import dis
import mymodule

# Смотрим байт-код
dis.dis(mymodule.calculate)
# LOAD_FAST 0 (x)
# LOAD_CONST 1 (2)
# BINARY_MULTIPLY
# RETURN_VALUE

Шаг 2: Интерпретация

По созданному байт-коду работает интерпретатор PVM (Python Virtual Machine), который выполняет инструкции:

# Интерпретатор выполняет каждую инструкцию
# LOAD_FAST 0 → загрузить переменную x со стека
# LOAD_CONST 1 → загрузить константу 2
# BINARY_MULTIPLY → выполнить умножение
# RETURN_VALUE → вернуть результат

Почему путаница?

Классическое определение

  • Компилируемый язык (C, C++, Go): исходный код → машинный код → прямое выполнение процессором
  • Интерпретируемый язык (JavaScript, Ruby): исходный код → прямое выполнение интерпретатором

Python не совпадает с обоими определениями в чистом виде.

Сравнение подходов

# Компилируемый язык (C)
// hello.c
#include <stdio.h>
int main() {
    printf("Hello\n");
    return 0;
}
// Компиляция: gcc hello.c -o hello
// Исполнение: ./hello

# Интерпретируемый язык (JavaScript в Node.js)
// hello.js
console.log("Hello");
// Исполнение: node hello.js (интерпретирует на лету)

# Python — гибридный подход
# hello.py
print("Hello")
# Исполнение: python hello.py
# На самом деле: компиляция в .pyc + интерпретация PVM

Реальная работа Python

import timeit
import sys

# Первое исполнение (компиляция в байт-код)
import time
start = time.time()
import numpy  # При импорте происходит компиляция
first_import_time = time.time() - start

# Второе исполнение (из кэша .pyc)
start = time.time()
import numpy  # Из кэша, быстрее
second_import_time = time.time() - start

print(f"Первый импорт: {first_import_time:.4f}s")
print(f"Второй импорт: {second_import_time:.4f}s")
# Второй импорт обычно на 10-50% быстрее

Различные реализации Python

Разные реализации используют разные подходы:

# CPython (стандартная реализация) — компилирует в байт-код + интерпретирует
# python hello.py → компиляция + интерпретация

# Jython (Python на JVM) — компилирует в Java байт-код
# jython hello.py → компиляция в .class + JVM JIT

# IronPython (Python на .NET) — компилирует в IL код
# ipy hello.py → компиляция в IL + .NET JIT

# PyPy (Python с JIT компилятором) — интерпретирует, потом JIT компилирует
# pypy hello.py → интерпретация + JIT компиляция в машинный код

# Cython — компилирует в C, потом в машинный код
# cython hello.pyx → C код → машинный код

Производительность

Потому что Python интерпретируется (даже с байт-кодом), он медленнее компилируемых языков:

import time

# Python (медленно)
start = time.time()
result = sum(range(1000000))
python_time = time.time() - start
print(f"Python: {python_time:.4f}s")

# Ускорение с помощью NumPy (C код)
import numpy as np
start = time.time()
result = np.arange(1000000).sum()
numpy_time = time.time() - start
print(f"NumPy: {numpy_time:.4f}s")

# NumPy может быть в 10-100x быстрее
print(f"Ускорение: {python_time / numpy_time:.1f}x")

Кэширование байт-кода

# Смотрим кэш
import os
for root, dirs, files in os.walk('__pycache__'):
    for file in files:
        if file.endswith('.pyc'):
            pyc_path = os.path.join(root, file)
            print(f"Кэшированный файл: {pyc_path}")

# Можно удалить кэш, Python создаст новый
import shutil
shutil.rmtree('__pycache__')

Ответ на собеседовании

Правильный и полный ответ:

Python — это интерпретируемый язык, но технически он использует гибридный подход:

1. Исходный код сначала компилируется в байт-код (.pyc файлы)
2. Затем байт-код интерпретируется виртуальной машиной Python (PVM)
3. На каждой инструкции PVM выполняет соответствующую операцию

По сравнению с чистыми компилируемыми языками (C, C++) Python медленнее,
потому что не компилируется в машинный код, который выполняется напрямую процессором.

Однако есть способы ускорения:
- PyPy (JIT компилятор)
- Cython (скомпилировать в C)
- NumPy/pandas (написаны на C)

Практические следствия

  1. Нет этапа явной компиляции — пишешь код и сразу запускаешь
  2. Ошибки видны только при исполнении — нет статической проверки типов (до Python 3.5+)
  3. Медленнее компилируемых языков — для критичного по производительности кода нужна оптимизация
  4. Кроссплатформенность — один код работает везде, где есть Python
  5. Кэширование — .pyc файлы ускоряют повторное исполнение

Заключение

Когда спрашивают: "Python компилируемый или интерпретируемый?" — правильный ответ:

"Python — язык с интерпретацией, но с трёхстадийной обработкой: парсинг → компиляция в байт-код → интерпретация PVM. По поведению и использованию это интерпретируемый язык, потому что нет явного этапа компиляции, как в C++."

Python компилируемый или интерпретируемый язык программирования | PrepBro