Pythonはインタプリタ言語であることを理解するために与えられました...
しかし、Pythonソースコードを見ると.pyc
、Windowsが「コンパイルされたPythonファイル」と識別するファイルが表示されます。
これらはどこから来るのですか?
java
とjavac
。
Pythonはインタプリタ言語であることを理解するために与えられました...
しかし、Pythonソースコードを見ると.pyc
、Windowsが「コンパイルされたPythonファイル」と識別するファイルが表示されます。
これらはどこから来るのですか?
java
とjavac
。
回答:
それらには、Pythonインタープリターがソースをコンパイルするバイトコードが含まれています。このコードは、Pythonの仮想マシンによって実行されます。
Pythonのドキュメントでは、次のように定義を説明しています。
コンパイルされたものとは対照的に、Pythonはインタプリタ言語ですが、バイトコードコンパイラが存在するため、区別がぼやけることがあります。これは、実行可能ファイルを明示的に作成せずにソースファイルを直接実行できることを意味します。
Pythonがインタプリタ言語であることを理解するために与えられました...
この人気のミームは正しくない、または(自然な)言語レベルの誤解に基づいて構築されています。同様の間違いは、「聖書はハードカバーの本です」と言うことです。その類似点を説明しましょう...
「聖書」とは、(実際に存在する、物理的な対象物として識別される)本のクラスという意味の「本」です。「聖書のコピー」として識別された本は、基本的な共通点があると思われます(内容は、異なる言語であっても、許容される翻訳、脚注のレベル、およびその他の注釈が異なる場合があります)-ただし、これらの本は基本とは見なされない無数の側面で完全に異なることが許可されています-綴じの種類、綴じの色、印刷に使用されるフォント、ある場合はイラスト、書き込み可能な余白が広いかどうか、組み込みブックマークの数と種類など。
聖書の典型的な印刷が実際にハードカバーの製本である可能性はかなりあります-結局のところ、それは通常、何度も何度も読まれ、いくつかの場所でブックマークされ、与えられた章と節へのポインタを探すことでつまづかれる本です。など、そして適切なハードカバーの綴じ方は、そのような使用下で所定のコピーをより長く持続させることができます。ただし、これらはありふれた(実用的な)問題であり、特定の実際の書籍オブジェクトが聖書のコピーであるかどうかを判断するために使用することはできません。ペーパーバック印刷は完全に可能です!
同様に、Pythonは言語実装のクラスを定義するという意味で「言語」であり、基本的な点(構文、明示的に異なることが許可されている部分以外のほとんどのセマンティクス)はすべて類似している必要がありますが、完全に許可されています。与えられたソースファイルの扱い方、ソースをいくつかの低レベルフォームにコンパイルするかどうか(そうであれば、どのフォームか)、およびそれらを保存するかどうかなど、ほぼすべての「実装」の詳細を変えるコンパイルされたフォーム、ディスクまたはその他の場所)、フォームの実行方法など。
古典的な実装であるCPythonは、略して単に「Python」と呼ばれることが多いですが、MicrosoftのIronPython(CLRコード、つまり「.NET」にコンパイルされる)、Jythonと並んで、いくつかの製品品質の実装の1つにすぎません。 (JVMコードにコンパイル)、PyPy(Python自体で記述され、「ジャストインタイム」で生成されたマシン言語を含む非常に多様な「バックエンド」フォームにコンパイルできます)。これらはすべて、Python(== "Python言語の実装")であり、表面的に異なる多くの本のオブジェクトがすべて聖書(== "Thecopible of the Bible")であるのと同じです。
特にCPythonに興味がある場合:ソースファイルをPython固有の下位レベルのフォーム(「バイトコード」と呼ばれる)にコンパイルし、必要に応じて(ソースファイルに対応するバイトコードファイルがない場合、またはバイトコードファイルはソースよりも古いか、別のPythonバージョンでコンパイルされています)。通常、バイトコードファイルをディスクに保存します(将来再コンパイルされないようにするため)。OTOH IronPythonは通常、CLRコード(ディスクに保存するかどうかに応じて)にコンパイルし、JythonをJVMコード(ディスクに.class
保存するかどうか)にコンパイルします。保存する場合は、拡張機能を使用します。
これらの下位レベルのフォームは、「インタープリター」とも呼ばれる適切な「仮想マシン」(CPython VM、.Netランタイム、Java VM(別名JVM))によって適切に実行されます。
したがって、この意味で(典型的な実装は何をするのか)、Pythonは「解釈された言語」であり、C#とJavaがそうである場合に限り、それらすべてに、最初にバイトコードを生成し、次にVM /インタープリターを介して実行するという典型的な実装戦略があります。 。
おそらくフォーカスは、コンパイルプロセスがいかに「重く」、遅く、ハイセレモニーであるかです。CPythonは、可能な限り少ない式で、可能な限り高速に、可能な限り軽量にコンパイルするように設計されています-コンパイラーはエラーチェックと最適化をほとんど行わないため、高速かつ少量のメモリで実行できるため、ほとんどの場合、ユーザーはコンパイルが行われていることを意識する必要さえなく、必要なときにいつでも自動的かつ透過的に実行されます。エラーをより徹底的にチェックし、より多くの最適化を実行するために、JavaおよびC#は通常、コンパイル中により多くの作業を受け入れます(したがって、自動コンパイルを実行しません)。連続したグレースケールであり、黒や白の状況ではありません。
インタプリタ言語のようなものはありません。インタープリターが使用されるかコンパイラーが使用されるかは、純粋に実装の特性であり、言語とはまったく関係がありません。
すべての言語は、インタープリターまたはコンパイラーによって実装できます。大多数の言語には、各タイプの実装が少なくとも1つあります。(たとえば、CとC ++にはインタープリターがあり、JavaScript、PHP、Perl、Python、Rubyにはコンパイラーがあります。)さらに、現代の言語実装の大部分は、インタープリターとコンパイラー(または複数のコンパイラー)の両方を実際に組み合わせています。
言語は抽象的な数学的なルールのセットです。インタプリタは、言語のいくつかの具体的な実装戦略の1つです。これら2つは、完全に異なる抽象化レベルにあります。英語が型付き言語である場合、「解釈された言語」という用語は型エラーになります。「Pythonはインタプリタ言語です」という文は単にfalseであるわけではありません(falseであることは、文が間違っていても意味があることを意味するため)、言語を次のように定義することはできないため、単純に意味がありません。「解釈された」
特に、現在存在するPythonの実装を見てみると、これらは使用している実装戦略です。
リストの実装のすべて(tinypy、Shedskin、Psycoなど、私が言及しなかった他の実装も)にはコンパイラーがあることに気付くでしょう。実際、私が知る限り、現時点では純粋に解釈されるPython実装はなく、そのような実装は計画されておらず、そのような実装はこれまでありません。
「解釈された言語」という用語が意味をなさないだけでなく、「解釈された実装の言語」を意味すると解釈しても、それは明らかに真実ではありません。誰が言ったのか、彼が何について話しているのかは明らかにわかりません。
特に、表示.pyc
されているファイルは、CPython、Stackless Python、またはUnladen Swallowによって生成されたキャッシュされたバイトコードファイルです。
これらは、.py
ファイルのインポート時にPythonインタープリターによって作成され、インポートされたモジュール/プログラムの「コンパイル済みバイトコード」が含まれます。つまり、ソースコードからバイトコードへの「変換」は1回だけ実行する必要があります。が対応するファイルよりも新しいimport
場合、後続のでスキップできます。これにより、起動が少し速くなります。しかし、それはまだ解釈されています。.pyc
.py
モジュールのロードを高速化するために、Pythonはモジュールのコンパイル済みコンテンツを.pycにキャッシュします。
CPythonはソースコードを「バイトコード」にコンパイルします。パフォーマンス上の理由から、ソースファイルに変更があった場合は常に、このバイトコードをファイルシステムにキャッシュします。これにより、コンパイルフェーズをバイパスできるため、Pythonモジュールの読み込みがはるかに高速になります。ソースファイルがfoo.pyの場合、CPythonはバイトコードをソースのすぐ隣のfoo.pycファイルにキャッシュします。
python3では、Pythonのインポート機構が拡張されて、すべてのPythonパッケージディレクトリ内の単一のディレクトリでバイトコードキャッシュファイルの書き込みと検索が行われます。このディレクトリは__pycache__と呼ばれます。
以下は、モジュールのロード方法を説明するフローチャートです。
詳細については:
ref:PEP3147
ref:「コンパイルされた」Pythonファイル
これは初心者向けです
Pythonは、スクリプトを実行する前に、スクリプトをコンパイルされたコード(いわゆるバイトコード)に自動的にコンパイルします。
スクリプトの実行はインポートとは見なされず、.pycは作成されません。
スクリプトファイルがある場合たとえば、abc.pyその輸入、別のモジュールxyz.pyを使用すると、実行すると、abc.py、xyz.pycは XYZがインポートされるために作成されますが、ないabc.pycファイルがされます作成されていない ABC以来。 pyはインポートされていません。
インポートされていないモジュールの.pycファイルを作成する必要がある場合は、py_compile
およびcompileall
モジュールを使用できます。
py_compile
モジュールは任意のモジュールを手動でコンパイルできます。1つの方法はpy_compile.compile
、そのモジュールの関数をインタラクティブに使用することです。
>>> import py_compile
>>> py_compile.compile('abc.py')
これにより、.pycがabc.pyと同じ場所に書き込まれます(オプションのパラメーターで上書きできますcfile
)。
compileallモジュールを使用して、ディレクトリ内のすべてのファイルを自動的にコンパイルすることもできます。
python -m compileall
ディレクトリ名(この例では現在のディレクトリ)を省略した場合、モジュールは、 sys.path
Python(少なくとも最も一般的な実装)は、元のソースをバイトコードにコンパイルしてから、仮想マシンでバイトコードを解釈するパターンに従います。これは(繰り返しますが、最も一般的な実装)は、純粋なインタプリタでもコンパイラでもありません。
ただし、これとは逆に、コンパイルプロセスはほとんど隠されています-.pycファイルは基本的にキャッシュのように扱われます。彼らは物事をスピードアップしますが、あなたは通常それらをまったく意識する必要はありません。必要に応じて、ファイルの時刻/日付スタンプに基づいて、それらを自動的に無効にして再ロードします(ソースコードを再コンパイルします)。
この問題が発生したのは、コンパイルされたバイトコードファイルが何らかの形で将来のタイムスタンプを取得したときだけでした。つまり、常にソースファイルよりも新しく見えました。見た目が新しくなったため、ソースファイルは再コンパイルされなかったため、どのような変更を加えても無視されました...
Pythonの* .pyファイルは、テキストファイルであり、そこにコード行を記述します。「python filename.py」と言ってこのファイルを実行しようとすると
このコマンドは、Python仮想マシンを呼び出します。Python仮想マシンには、「コンパイラ」と「インタプリタ」の2つのコンポーネントがあります。インタープリターは* .pyファイル内のテキストを直接読み取ることができないため、このテキストは最初にPVM (ハードウェアではなくPVM)をターゲットとするバイトコードに変換されます。PVMはこのバイトコードを実行します。* .pycファイルは、シェルまたは他のファイルでインポート操作を実行する実行の一部としても生成されます。
この* .pycファイルがすでに生成されている場合、次に* .pyファイルを実行/実行するたびに、システムはコンパイルを必要としない* .pycファイルを直接ロードします(これにより、プロセッサのマシンサイクルがいくらか節約されます)。
* .pycファイルが生成されたら、編集しない限り、*。pyファイルは必要ありません。