CPython、JPython、IronPython、PyPyがどのように異なるのかを理解するのにも同じ問題がありました。
だから、私が説明を始める前に、3つのことをクリアしたいと思います:
- Python:これは言語であり、インタプリタ(Pythonコードを受け入れるプログラム)に自分を伝達/表現する方法を記述/説明するだけです。
- 実装:それはすべてのインタプリタが、具体的には、書かれていたかについてであるどのような言語にし、何それはやって終わります。
- バイトコード:これは、「実際の」コンピュータマシンであるハードウェアプロセッサではなく、通常は仮想マシンと呼ばれるプログラムによって処理されるコードです。
CPythonはC言語で書かれた実装です。最終的に、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行目では、CPython(インタープリター)によって生成された中間のPythonバイトコード(またはPythonバイトコードの逆アセンブラー)を表示するために使用できる「dis」モジュールをインポートします。
注:#python IRCチャネルからこのコードへのリンクを取得しました:https ://gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c
そして、Javaで記述され、最終的にJavaバイトコードを生成するJythonがあります。Javaバイトコードは、Java仮想マシン(JVM)の実装であるJavaランタイム環境で実行されます。これが混乱している場合は、Javaがどのように機能するのか手掛かりがないと思います。簡単に言えば、Java(コンパイラではなく言語)コードはJavaコンパイラによって取得され、JREを使用してのみ実行できるファイル(Javaバイトコード)を出力します。これは、Javaコードがコンパイルされると、JREのみが実行できるJavaバイトコード形式で他のマシンに移植できるようにするために行われます。これでも混乱する場合は、このWebページをご覧ください。
ここでは、CPythonのバイトコードがJythonのように移植可能かどうかを尋ねるかもしれませんが、そうではないと思います。CPythonの実装で生成バイトコードは、コードのさらなる実行のために簡単にそれを作るためにそのインタプリタに対して特異的であった(私は、また、処理の多くの他の通訳で行われるだけで容易にするために、そのような中間バイトコード生成を疑います)。
したがって、Jythonでは、Pythonコードをコンパイルすると、JVMで実行できるJavaバイトコードが生成されます。
同様に、IronPython(C#言語で記述)は、Pythonコードを共通言語ランタイム(CLR)にコンパイルします。これは、Microsoftが開発したJVMと比較して類似したテクノロジーです。