Pythonにコンパイラが必要ないのはなぜですか?


29

Pythonがコンパイラを必要としないのはなぜだろうか(コンパイラを必要とするC ++で始めたのだ)

コードを入力して、execとして保存し、実行するだけです。C ++では、ビルドとその他すべての楽しいものを作成する必要があります。


4
Pythonは、多くの実装を備えた単なる言語です。Iron Pythonは、C#とC ++がコンパイルされるのと同じ方法でコンパイルされますが、他にも同様の実装が存在する場合があります。
仕事

1
C#とC ++は同じ方法でコンパイルされません-どちらも最終的には機械語命令になると主張することもできますが、そうすれば、BASICも同じ方法でコンパイルされると言えます。
-gbjbaanb

7
@gbjbaanbしかし、その後、再び英語がコンパイルされておらず、一つの文の意味解析は、2つの等しく有効な結果をもたらす可能性があり、上記の「鉄のpythonは、C#やC ++がコンパイルされると同じようにコンパイルされている」として読み取ることができる
ルーンFS

Pythonコードの記述に使用しているプラ​​ットフォーム/ソフトウェアは何ですか?.pyファイルを作成する場合、それは実行可能ファイルではありません。まだソースコードファイルです。コマンドラインから、コマンドを使用しpythonて.pyファイルを解釈するか、IDLEまたはEclipseを使用する場合、IDEが自動的に実行します。
リックヘンダーソン

回答:


68

Pythonにはコンパイラがあります!自動的に実行されるため、気づかないだけです。ただし、そこにあることはわかります。自分のモジュール用に生成されたファイル.pyc(または.pyoオプティマイザーを有効にしている場合)を見てくださいimport

また、ネイティブマシンのコードにコンパイルしません。代わりに、仮想マシンで使用されるバイトコードにコンパイルします。仮想マシン自体はコンパイルされたプログラムです。これは、Javaの動作に非常に似ています。実際、非常に似ており、代わりにJava仮想マシンのバイトコードにコンパイルされるPythonバリアント(Jython)があります!また、MicrosoftのCLR(.NETで使用)にコンパイルされるIronPythonもあります。(通常のPythonバイトコードコンパイラは、これらの選択肢と区別するためにCPythonと呼ばれることもあります。)

C ++は、言語自体が不完全であるため、コンパイルプロセスを公開する必要があります。プログラムをビルドするためにリンカが必要とするすべてを指定するわけではなく、コンパイルオプションを移植可能に指定することもできません(一部のコンパイラではを使用できますが#pragma、これは標準ではありません)。したがって、メイクファイルと場合によっては自動地獄(autoconf / automake / libtool)で残りの作業を行う必要があります。これは、実際にCがそれを行った方法からのホールドオーバーです。そして、Cがそのようにしたのは、コンパイラが簡単になったからです。これが人気の理由の1つです(80年代に誰でも簡単なCコンパイラを開発できたのです)。


コンパイラまたはリンカーの動作に影響を与える可能性があるが、CまたはC ++の構文内で指定されていないもの:

  • 依存関係の解決
  • 外部ライブラリの要件(依存関係の順序を含む)
  • 最適化レベル
  • 警告設定
  • 言語仕様バージョン
  • リンカマッピング(最終プログラムのどこに行くか)
  • ターゲットアーキテクチャ

これらの一部は検出できますが、指定することはできません。たとえば、どのC ++がで使用されているかを検出__cplusplusできますが、C ++ 98がコード内でコードに使用されていることを指定できません。Makefileでフラグとしてコンパイラーに渡すか、ダイアログで設定する必要があります。

「依存関係解決」システムがコンパイラに存在し、依存関係レコードを自動的に生成すると考えるかもしれませんが、これらのレコードは特定のソースファイルが使用するヘッダーファイルのみを示します。実行可能プログラムにリンクするために追加のソースコードモジュールが必要かどうかを示すことはできません。CまたはC ++には、特定のヘッダーファイルが単なる束ではなく別のソースコードモジュールのインターフェイス定義であることを示す標準的な方法がないためです繰り返したくないように、複数の場所に表示したい行。ファイルの命名規則には伝統がありますが、これらはコンパイラとリンカによって知られていないか強制されていません。

これらのいくつかはを使用して設定できます#pragmaが、これは非標準であり、標準について話していました。これらはすべて、標準で指定できますが、下位互換性のために作成されたものでありません。一般的な知恵は、メイクファイルとIDEが破損しないため、修正しないでください。

Pythonはこのすべてを言語で処理します。たとえばimport、明示的なモジュール依存関係を指定し、依存関係ツリーを暗黙指定し、モジュールはヘッダーファイルとソースファイル(つまり、インターフェイスと実装)に分割されません。


3
PythonのC実装はCPythonでCythonは別のものです。
グレッグヒューギル

4
Cがマシンコードにコンパイルされた他の理由は、バイトコードインタープリターがハードウェア上で技術的に実行不可能であり、最も重要なタスクの1つがOSカーネルの作成であったためです。
tdammers

2
@BillyONealは、c / c ++ではプログラマとして特定の方法(メイクファイルまたはすべてを同じblobにダンプ)で行う必要があるという1つの大きな例外があります。Pythonでは、作業とコンパイラをVMと一緒に行うだけです。残りの面倒を見る
ルーンFS

3
「言語自体が不完全であるため、C ++はコンパイルプロセスを公開する必要がある」のEr、何を?
モニカとの軽さのレース

3
その直後の部分を読みますよね?「リンカがプログラムをビルドするために必要なすべてを指定するわけではなく、コンパイルオプションを移植可能に指定することもできません。」あなただけ構築することはできません任意のコンパイラにそれを供給することにより、C ++ファイルを、多くの場合、コンパイルフラグ、インクルードパスなどのメタデータを提供する必要があります。このメタデータは標準では指定されておらず、移植性もありません。そのため、make、cmake、Visual Studioなどにドラッグする必要がありますジョブを終了します。そのため、標準では、コンパイル単位のようにいくつかのことを、またプログラム全体として他のことを呼び出さなければなりません。
マイクデシモーネ

7

Pythonはインタープリター言語です。これは、Pythonコードを読み取り、「命令」をマシンに送信するソフトウェアがコンピューター上にあることを意味します。インタプリタ言語のWikipediaの記事は、興味があるかもしれません。

C ++(コンパイル済み言語)などの言語がコンパイルされると、実行時にハードウェアによって直接読み取られるマシンコードに変換されます。コンパイル言語でWikipediaの記事は面白いコントラストを提供するかもしれません。


21
インタプリタ言語やコンパイル済み言語などはありません。言語は、数学的なルールの抽象的なセットです。言語はコンパイルも解釈もされません。言語はただです。コンパイルと解釈は、言語ではなく、コンパイラーまたはインタープリターの特徴です!すべての言語はコンパイラーで実装でき、すべての言語はインタープリターで実装できます。ほとんどの言語には、コンパイルされた実装と解釈された実装の両方があります。C ++用のインタープリターがあり、Python用のコンパイラーがあります。(実際、現在存在するすべてのPython実装にはコンパイラーがあります。)
JörgW Mittag

4
最新の高性能言語実装の大部分は、インタープリターとコンパイラー(または複数のコンパイラー)の両方を組み合わせて最大のパフォーマンスを実現しています。実際に、不可能に実行する任意のプログラムをせずにインタプリタ。結局のところ、コンパイラは、ある言語から別の言語にプログラムを翻訳する単なるプログラムです。しかし、ある時点で、プログラムを実際に実行する必要があります。これはインタープリターによって実行されます(シリコンに実装されている場合とされていない場合があります)。
ヨルグWミットタグ

10
@JörgWMittag:あなたは技術的に正しいです。ただし、ほとんどの言語は、解釈されたコンテキストまたは完全なコンパイル用に設計されています。GW BASICまたはCommon Lispのインタプリタを記述する方が、たとえばC ++またはC#のインタプリタを記述するよりもはるかに簡単です。Pythonは、インタラクティブな環境なしではセールスポイントの多くを失います。PHP用のコンパイラーの作成は非常に難しく、恐らく恐ろしく非効率的です。コンパイルされた実行可能ファイルには、eval()および同様のコンストラクトがあるため、PHPインタープリター全体を含める必要があるためです。
tdammers

2
@tdammers、はい。「通常コンパイルされた言語」を意味する「コンパイルされた言語」を合理的に使用できます。しかし、PHP、Java、Python、Lua、およびC#がすべてバイトコードのコンパイラーとして実装されているという点を見逃しています。これらの言語にはすべて、JITが実装されています。したがって、実際には、これらの言語の一部はコンパイルされ、一部の言語は同じ実装戦略を持っているため、インタープリターを呼び出すことができません。
ウィンストンイーバート

2
@BillyONeal、少なくともpythonには当てはまりません。Pythonバイトコードを配布し、ソースなしで実行できます。しかし、コンパイラなしではpythonを配布できないことは事実です。
ウィンストンイーバート

5

コンパイルされたすべての言語に、面内編集-コンパイル-リンク-実行サイクルがあるわけではありません。

実行しているのは、C ++(または少なくともC ++実装)の機能/制限です。

何かを行うには、コードをファイルに保存し、リンクと呼ばれるプロセスでモノリシックイメージを構築する必要があります。

特に、コンパイルと解釈の区別と間違われるのは、このモノリシックリンクプロセスです。

一部の言語は、機械コードへのコンパイルを排除するのではなく、不器用なモノリシックリンク手順を排除することで、これらすべてをはるかに動的に行います。ソースは引き続きオブジェクトファイルにコンパイルされますが、これらはモノリシック実行可能ファイルにリンクされるのではなく、ランタイムイメージにロードされます。

「このモジュールをリロードする」と言うと、何らかのモード切り替えに応じて、ソースをロードして解釈するか、コンパイルします。

Linuxカーネルプログラミングには、Cで作業している場合でもこのような特徴があります。モジュールを再コンパイルして、ロードおよびアンロードできます。もちろん、あなたはまだ実行可能なものを作成していることを認識しており、それは複雑なビルドシステムによって管理されており、まだいくつかの手動ステップがあります。しかし、実際には、最終的にその小さなモジュールだけをアンロードおよび再ロードでき、カーネル全体を再起動する必要はありません。

一部の言語では、これよりもさらにきめ細かいモジュール化が行われており、ビルドとロードはランタイム内から行われるため、よりシームレスです。


2

最初の質問からの転換...言及されていない点は、Pythonプログラムのソースはあなたが使用して配布するものであり、ユーザーの観点からはそれがプログラムであるということです。よく定義されていないカテゴリに物事を単純化する傾向があります。

コンパイルされたプログラムは通常、マシンコードのスタンドアロンファイルと見なされます。(明らかに、特定のオペレーティングシステムに関連付けられたダイナミックリンクライブラリへのリンクが含まれていることがよくあります)。これは...コンパイルまたは解釈されると説明できるほとんどのプログラミング言語のバリエーションがあります。

Pythonは、簡単にアクセスまたは配布できる形式で作成されるマシンコードを保存せずにコードをコンパイルおよび実行するアプリケーション(インタープリターと呼ばれる)に依存するため、コンパイラーを必要としません。


1

すべてのプログラミング言語では、人間の概念をターゲットマシンコードに翻訳する必要があります。アセンブリ言語でさえ機械語に翻訳する必要があります。この変換は通常、次の段階で行われます。

フェーズ1:分析と中間コードへの変換(解析)。フェーズ2:外部参照用のプレースホルダーを使用して、中間コードをターゲットマシンコードに変換します。フェーズ3:外部参照の解決およびマシン実行可能プログラムへのパッケージ化。

この翻訳は、多くの場合、プリコンパイルおよび「ジャストインタイム」(JIT)またはランタイムコンパイルと呼ばれます。

C、C ++、COBOL、Fortran、Pascal(すべてではない)、およびAssemblyなどの言語は、インタープリターを必要とせずにオペレーティングシステムによって直接実行できるプリコンパイル言語です。

Java、BASIC、C#、Pythonなどの言語が解釈されます。それらはすべて、フェーズ1で作成された中間コードを使用しますが、マシンコードへの変換方法が異なる場合があります。最も単純な形式では、その中間コードを使用して、期待される動作を行うマシンコードルーチンを実行します。その他は、中間コードをマシンコードにコンパイルし、実行時に外部依存関係の修正を行います。コンパイルするとすぐに実行できます。同様に、マシンコードは以前にコンパイルされた再利用可能なマシンコードのキャッシュに保存され、後で関数が再び必要になった場合に後で再利用できます。関数が既にキャッシュされている場合、インタプリタは再度コンパイルする必要はありません。

最新の高レベル言語は、インタプリタ(JITを使用)カテゴリに分類されます。プリコンパイルされるのは、主にCやC ++などの古い言語です。

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