Даже у меня была та же проблема понимания того, как CPython, JPython, IronPython, PyPy отличаются друг от друга.
Итак, я хочу прояснить три вещи, прежде чем я начну объяснять:
- Python : Это язык, он только устанавливает / описывает, как передать / выразить себя интерпретатору (программе, которая принимает ваш код Python).
- Реализация : все дело в том, как был написан переводчик, в частности, на каком языке и что он в итоге делает .
- Байт-код : это код, который обрабатывается программой, обычно называемой виртуальной машиной, а не «реальной» компьютерной машиной, аппаратным процессором.
CPython - это реализация, написанная на языке Си. Он заканчивает тем, что производит байт-код (набор команд на основе стека), который является специфичным для Python, а затем выполняет его. Причина преобразования кода Python в байт-код заключается в том, что легче реализовать интерпретатор, если он выглядит как машинные инструкции. Но нет необходимости создавать некоторый байт-код перед выполнением кода Python (но CPython действительно производит).
Если вы хотите посмотреть байт-код CPython, тогда вы можете. Вот как вы можете:
>>> def f(x, y): # line 1
... print("Hello") # line 2
... if x: # line 3
... y += x # line 4
... print(x, y) # line 5
... return x+y # line 6
... # line 7
>>> import dis # line 8
>>> dis.dis(f) # line 9
2 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('Hello')
4 CALL_FUNCTION 1
6 POP_TOP
3 8 LOAD_FAST 0 (x)
10 POP_JUMP_IF_FALSE 20
4 12 LOAD_FAST 1 (y)
14 LOAD_FAST 0 (x)
16 INPLACE_ADD
18 STORE_FAST 1 (y)
5 >> 20 LOAD_GLOBAL 0 (print)
22 LOAD_FAST 0 (x)
24 LOAD_FAST 1 (y)
26 CALL_FUNCTION 2
28 POP_TOP
6 30 LOAD_FAST 0 (x)
32 LOAD_FAST 1 (y)
34 BINARY_ADD
36 RETURN_VALUE
Теперь давайте посмотрим на приведенный выше код. Строки с 1 по 6 являются определением функции. В строке 8 мы импортируем модуль 'dis', который можно использовать для просмотра промежуточного байт-кода Python (или, можно сказать, дизассемблера для байт-кода Python), который генерируется CPython (интерпретатором).
ПРИМЕЧАНИЕ . Я получил ссылку на этот код с IRC-канала #python: https://gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c.
И затем, есть Jython, который написан на Java и в конечном итоге производит байт-код Java. Байт-код Java работает в среде выполнения Java, которая является реализацией виртуальной машины Java (JVM). Если это сбивает с толку, то я подозреваю, что вы понятия не имеете, как работает Java. С точки зрения непрофессионала, код Java (язык, а не компилятор) берется компилятором Java и выводит файл (который является байтовым кодом Java), который может быть запущен только с использованием JRE. Это сделано для того, чтобы после компиляции кода Java его можно было перенести на другие машины в формате байтового кода Java, который может выполняться только JRE. Если это все еще сбивает с толку, то вы можете взглянуть на эту веб-страницу .
Здесь вы можете спросить, является ли байт-код CPython переносимым, как Jython, я подозреваю, что нет. Байткодом производится в реализации CPython был специально для этого переводчиком , что делает его легким для дальнейшего выполнения кода (я подозреваю , что такое промежуточное производство байткодом, просто для удобства обработки делается во многих других переводчиков).
Итак, в Jython, когда вы компилируете свой код Python, вы получаете Java-байт-код, который может быть запущен на JVM.
Точно так же IronPython (написанный на языке C #) компилирует ваш код Python в Common Language Runtime (CLR), который является аналогичной технологией по сравнению с JVM, разработанным Microsoft.