Pythonは解釈、コンパイル、またはその両方ですか?


190

私の理解から:

インタプリタ言語は、高レベルの言語で実行されると、外出先でインタプリタ(機械コードに高レベルの言語を変換した後、実行中のプログラム)によって実行されます。少しずつプログラムを処理します。

コンパイルされた言語は、そのコードの最初のコンパイラ(マシンコードに高レベル言語に変換するプログラム)によって機械コードに変換してエグゼキュータ(コードを実行するための別のプログラム)によって実行される高級言語です。

定義が間違っている場合は修正してください。

Pythonに戻ると、これについて少し混乱しています。Pythonはインタプリタ言語であることをどこでも知っていますが、それはいくつかの中間コード(バイトコードやILなど)に解釈され、マシンコードには解釈されません。では、どのプログラムがIMコードを実行するのでしょうか。Pythonスクリプトがどのように処理され、実行されるかを教えてください。



2
Pythonは、ライブラリがインポートされるたびに.pycファイル(いわゆるbyecode)を作成します。私の知る限り、バイトコードは実行時間ではなく、ロード時間のみを高速化できます。
Jesvin Jose、2011

2
@aitchnyu:.pycファイルでバイトコードをキャッシュすると、実際にロードが高速化されるだけですが、Pythonコードが実行前にバイトコードにコンパイルされる場合のみです。特にPythonで試されたとは思いませんが、他の言語の実装では、バイトコードの方がプレーンなASTまたはさらに悪いことに、解析されていないソースコードよりも効率的に解釈しやすいことが示されています。たとえば、古いバージョンのRubyはASTから解釈され、AFAIKはバイトコードにコンパイルされる新しいバージョンよりもかなりパフォーマンスが優れていました。

失礼に聞こえたくないのですが、それは私が意図したことではありません(ただし、あなたほど情報が豊富ではありません)。
Jesvin Jose、2011

1
@aitchnyu:どういう意味かわかりません。私はあなたのコメントが正しくなかったことを知っているだけですが、それがロード時間を短縮するだけの理由の背景情報に良い機会を提供したので、その情報を追加することにしました。違反の意味または取られたものではありません:)

回答:


231

まず、インタプリタ/コンパイルは言語のプロパティではなく、実装のプロパティです。ほとんどの言語では、すべてではないにしてもほとんどの実装が1つのカテゴリに分類されるため、言語が解釈/コンパイルされていることを示すいくつかの単語を節約できますが、理解を助けるためとかなりの数の言語があるため、それは依然として重要な区別です両方の種類の使用可能な実装(主に関数型言語の領域で、HaskellとMLを参照)。さらに、PythonのサブセットをCまたはC ++コード(さらにはマシンコード)にコンパイルしようとするCインタープリターとプロジェクトがあります。

次に、コンパイルはネイティブマシンコードへの事前コンパイルに制限されません。コンパイラーは、より一般的には、あるプログラミング言語のプログラムを別のプログラミング言語のプログラムに変換するプログラムです(重要な変換が適用される場合、おそらく同じ入力言語と同じ出力言語のコンパイラーを持つこともできます)。そして、JITコンパイラーは実行時にネイティブマシンコードにコンパイルします。これにより、事前コンパイルに非常に近いか、それよりも優れた速度が得られます(ベンチマークと比較した実装の品質によって異なります)。

しかし、つまらないことをやめて、あなたが尋ねるつもりだった質問に答えるために:実用的に(読む:やや人気のある成熟した実装を使用して)、Pythonがコンパイルされます。事前にマシンコードにコンパイルされていない(つまり、制限された間違ったものによって「コンパイルされた」が、悲しいことに一般的な定義)、バイトコードに「のみ」コンパイルされたが、それでもコンパイルには少なくともいくつかの利点がある。たとえば、ステートメントa = b.c()はバイトストリームにコンパイルされ、バイトストリームは「逆アセンブル」されると、のように見えload 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a)ます。これは単純化であり、実際には読みにくく、もう少し低レベルです。標準ライブラリdisモジュールを試して、実際の取引がどのように見えるかを確認できます。

そのバイトコードは、リファレンス実装(CPython)と同様に解釈されるか(理論と実際のパフォーマンスの両方で、直接解釈と最初のコンパイルから中間表現への解釈と解釈には違いがある)、または解釈とコンパイルの両方が行われますPyPyと同様に、実行時に最適化されたマシンコード。


2
さて、Pythonスクリプトは、最初のバイトコードにコンパイルされ、その後、それはCPythonの、JythonのまたはIronPythonの等のようなインタプリタによって実現されることがこの手段
パンカジUpadhyay

19
いいえ、バイトコードにコンパイルされ、バイトコードはそれぞれのVMによって実行されます。CPythonはコンパイラとVMの両方ですが、JythonとIronPythonは単なるコンパイラです。
Ignacio Vazquez-Abrams

1
@Igacio:IronPython / Jythonの経験はあまりありませんが、少なくともJythonはインタープリターのようなレイヤーを提供していませんか?Pythonを静的に型付けされたJVMバイトコードに変換するのは現実的ではないと思います。それでも、コンパイラーとインタープリターが同じパッケージの一部であることの良い点。

2
+1 "...実装のプロパティ"。私自身は「インタラクティブなシェルを可能にする」と言っただろう
Jesvin Jose

2
@delnan:まあ、JythonはPython言語とJava VMの間の一種の仲介者として機能しますが、Javaバイトコードにコンパイルします。
イグナシオバスケスアブラムス

34

CPUが実際に理解できるのはマシンコードだけです。インタープリター型プログラムの場合、インタープリターの最終的な目標は、プログラムコードをマシンコードに「解釈」することです。ただし、通常、現代のインタープリター型言語は非効率的であるため、人間のコードを直接解釈しません。

Pythonインタープリターは、最初に人間のコードを読み取り、それをいくつかの中間コードに最適化してから、マシンコードに解釈します。そのため、コンパイルされたコードの実行可能ファイルを直接実行できるC ++とは異なり、Pythonスクリプトを実行するには常に別のプログラムが必要です。たとえば、c:\Python27\python.exeまたは/usr/bin/python


11
「別のプログラムを実行する必要がある」という点が気に入っています。それは私の考えのいくつかを明確にするのに役立ちました。
マット

python.exeは最初にコードを最適化してから解釈しますか?
Koray Tugay 2015年

@ KorayTugay、python.exeに人間が読めるテキストソースコードが与えられると、最初に最適化されたバイトコードが生成され、それが(あなたの言うとおり)解釈されます。ただし、バイトコードファイル(コンパイル済み)が既に存在する場合は、最初の手順を実行する必要がないため、時間を節約できます。
GordonBGood 2016年

31

答えは、使用されているpythonの実装によって異なります。使用している場合は、CPython(Pythonの標準実装)またはJython(Javaプログラミング言語との統合を対象としています)を最初にバイトコードに変換し、使用しているPythonの実装に応じて、このbycodeは対応する解釈のための仮想マシン。CPython用のPVM(Python仮想マシン)およびJython用のJVM(Java仮想マシン)。

しかし、別の標準CPython実装であるPyPyを使用しているとしましょう。これは、使用するジャストインタイムコンパイラを


バイトコードへの変換中、コンパイラはどれですか?
RICKY

PypyはPythonの実装であり、「CPython」の実装ではありません。実際、PypyはCPythonに代わるものです(pypy.org/features.html)。
ジョルジオ

13

Pythonの公式ウェブサイトによると、これはインタープリター型言語です。

https://www.python.org/doc/essays/blurb/

Pythonはインタープリター型のオブジェクト指向の高水準プログラミング言語です...

...

コンパイルステップがないので......

...

Pythonインタープリターと広範な標準ライブラリが利用可能です...

...

代わりに、インタープリターがエラーを検出すると、例外が発生します。プログラムが例外をキャッチしない場合、インタプリタはスタックトレースを出力します。


7

はい、コンパイルされた言語と解釈された言語の両方です。 では、なぜそれを一般的にインタープリタ型言語と呼ぶのでしょうか?

それがどのようにコンパイルされ解釈されているかを見てください。

まず第一に、あなたがJavaの世界から来た方なら、私の答えをもっと気に入っていただけると思います。

Javaでは、ソースコードは最初にjavacコンパイラを介してバイトコードに変換され、次にJVMに送られます(実行目的でネイティブコードを生成します)。ここで、Javaをコンパイル済み言語として呼び出すことをお見せします。これは、Javaが実際にソースコードをコンパイルし、.classファイル(バイトコードのみ)を提供することがわかるためです。

javac Hello.java -------> Hello.classファイルを生成します

java Hello --------> 実行目的でバイトコードをJVMに送信する

同じことがpythonでも発生します。つまり、最初にソースコードがコンパイラを介してバイトコードに変換され、次にPVMに送られます(実行目的でネイティブコードを生成します)。ここで、通常はPythonをインタープリタ言語として呼び出すことをお見せします。コンパイルは舞台裏 で行われるため、Pythonコードを実行するときに次のようになります。

python Hello.py ------->コードを直接実行し、コードが構文的に正しいことを証明する出力を確認できます

@ python Hello.pyそれは直接実行されるように見えますが、実際には最初に、インタープリターによって解釈されるバイトコードを生成して、実行目的のネイティブコードを生成します。

CPython-コンパイルと解釈の両方の責任を負います。

詳細が必要な場合は、以下の行を調べてください

私がいることを言及したようにCPythonのは、ソースコードをコンパイルしますが、実際のコンパイルがの助けを借りて起こるcythonその後、解釈はの助けを借りて起こるCPythonの

次に、JavaとPythonにおけるJust-In-Timeコンパイラの役割について少し説明します。

JVMには、実行用のネイティブマシンコードを取得するためにバイトコードを1行ずつ解釈するJavaインタープリターが存在しますが、Javaバイトコードがインタープリターによって実行される場合、実行は常に遅くなります。それで、解決策は何ですか?解決策はジャストインタイムコンパイラーであり、解釈するよりもはるかに速く実行できるネイティブコードを生成します。一部のJVMベンダーはJavaインタープリターを使用し、一部はJust-In-Timeコンパイラーを使用しています。参照:ここをクリック

Pythonでは、インタープリターを回避して高速実行を実現するには、CPythonではなく別のPython実装(PyPy)を使用します。 PyPyを含むpythonの他の実装については、ここをクリックしてください


6

If(あなたはJavaを知っています){

Pythonコードは、javaのようにバイトコードに変換されます。
そのバイトコードは、アクセスしようとするたびに再度実行されます。

} else {

Pythonコードは、最初はバイトコード
と呼ばれるものに変換されますが、実際には機械語ではない
ため、アクセスまたは実行するたびに、バイトコードが再度実行されます

}


2

ほとんど、Pythonはインタプリタ言語であると言えます。しかし、Pythonでの1回限りのコンパイルプロセスの一部を使用して、完全なソースコードをJava言語のようなバイトコードに変換しています。


1

初心者向け

Pythonは、スクリプトを実行する前に、スクリプトをコンパイルされたコード(いわゆるバイトコード)に自動的にコンパイルします。

スクリプトの実行はインポートとは見なされず、.pycは作成されません。

たとえば、別のモジュールxyz.pyをインポートするスクリプトファイルabc.pyがある場合、abc.pyを実行すると、xyzがインポートされるためxyz.pycが作成されますが、abc以降はabc.pycファイルは作成されません。 pyはインポートされていません。


0

作成したpythonコードはpythonバイトコードにコンパイルされ、拡張子.pycのファイルが作成されます。コンパイルする場合、再び問題は、なぜコンパイルされた言語ではないかです。

これは、伝統的な意味でのコンパイルではないことに注意してください。通常、コンパイルは高級言語を取り、それを機械語コードに変換すると言います。しかし、それは一種の集まりです。マシンコードではなく中間コードにコンパイルされます(今すぐ入手してください)。

実行プロセスに戻ると、コンパイルステップで作成されたpycファイルに存在するバイトコードは、適切な仮想マシン(この場合はCPython VM)によって実行されます。タイムスタンプ(マジックナンバーと呼ばれます)を使用して、新しいpycファイルの作成に応じて、pyファイルが変更されるかどうか。pycが現在のコードの場合、コンパイル手順をスキップします。


0

Python(インタプリタ)がコンパイルされています。

証拠:構文エラーが含まれている場合、コードをコンパイルしません

例1:

print("This should print") 
a = 9/0 

出力:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

コードは正常にコンパイルされます。最初の行が実行されます(print)2番目の行がスローされZeroDivisionErrorます(実行時エラー)。

例2:

print("This should not print")
/0         

出力:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

結論:コードファイルにSyntaxError何も含まれていない場合、コンパイルが失敗するため実行されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.