質問

Python はインタープリター言語であることを理解させられました...しかし、Python のソースコードを見ると、 .pyc ファイル。Windows は「コンパイルされた Python ファイル」として識別します。これらはどこから入ってくるのでしょうか?

役に立ちましたか?

解決

それらが中に含んでいる バイトコード, 、これがPythonインタープリターがソースをコンパイルするものです。このコードは、Pythonの仮想マシンによって実行されます。

Pythonのドキュメントは、次のような定義を説明しています。

Pythonはコンパイルされた言語とは対照的に解釈された言語ですが、Bytecodeコンパイラの存在のために区別はぼやけている可能性があります。つまり、ソースファイルは、実行可能ファイルを明示的に作成することなく直接実行できることを意味します。

他のヒント

私はPythonが解釈された言語であることを理解するために与えられました...

この人気のあるミームは間違っているか、むしろ(自然な)言語レベルの誤解に基づいて構築されています。同様の間違いは、「聖書はハードカバーの本」と言うことです。その直mileを説明させてください...

「聖書」は「本」です。 クラス of(実際の、識別された物理オブジェクト)本。 「聖書のコピー」として特定された本は、共通の基本的なものを持っているはずです(内容も、さまざまな翻訳、脚注、その他の注釈のレベルがある異なる言語でもありますが、それらの本は、それらの本は無数の側面で異なることが完全に許可されている いいえ 基本的なものと考えられています - バインディングの種類、バインディングの色、印刷で使用されるフォント、もしあればイラスト、幅広い書き込みのあるマージンかどうか、数字とビルトインのブックマークの種類など。

a 典型的 聖書の印刷は確かにハードカバーのバインディングにあります - 結局のところ、それは通常、何度も何度も読むことを意図した本であり、いくつかの場所でブックマークされ、与えられた章とヴェースポインターなどを探して親指を立て、その他。優れたハードカバーバインディングは、そのような使用の下で特定のコピーを長持ちさせることができます。ただし、これらは、特定の実際の本オブジェクトが聖書のコピーであるかどうかを判断するために使用できない平凡な(実用的な)問題です。ペーパーバックの印刷は完全に可能です!

同様に、Pythonはクラスを定義するという意味での「言語」です 言語 実装 いくつかの基本的な点で類似している必要があります(構文、ほとんどのセマンティクスは、明示的に異なることを許可されている部分の部分を除く)が、ほぼすべての「実装」の詳細で完全に異なることを許可されています。ソースファイルが与えられたソースファイル、ソースをいくつかの低レベルのフォームにコンパイルするかどうか(そして、もしそうならフォーム - そのようなコンパイルされたフォームをディスクまたは他の場所に保存するかどうか)、彼らがそのフォームをどのように実行するかなど。

古典的な実装であるCpythonは、しばしば略して「Python」と呼ばれますが、MicrosoftのIronpython(CLRコード、つまり「.Net」にコンパイルする)、Jythonと並んで、いくつかの生産品質の実装の1つにすぎません。 (JVMコードにコンパイル)、Pypy(Python自体で書かれており、「Just-in-Time」生成された機械言語を含む多種多様な「バックエンド」フォームにコンパイルできます)。それらはすべて、多くの表面的に異なる本のオブジェクトと同じように、すべてPython(== "Python言語の実装")です(== "コピーの聖書")。

cpythonに特に興味がある場合は、ソースファイルをPython固有の低レベルのフォーム(「bytecode」と呼ばれる)にコンパイルします。必要に応じて自動的に実行します(ソースファイルに対応するバイトコードファイルがない場合、またはByteCodeファイルは、ソースよりも古いか、別のPythonバージョンでコンパイルされています)。通常、ByteCodeファイルをディスクに保存します(将来的に再コンパイルしないように)。 Otoh Ironpythonは通常、CLRコードにコンパイルします(ディスクに保存するかどうか、依存します)。 .class 拡張がそれらを保存する場合)。

これらの低レベルのフォームは、「通訳」とも呼ばれる適切な「仮想マシン」によって実行されます。CPYTHONVM、.NETランタイム、Java VM(別名JVM)。

したがって、この意味で(典型的な実装は何をしますか)、PythonはC#とJavaが次の場合にのみ「解釈された言語」です。それらはすべて、最初にbytecodeを生成し、VM/インタープリターを介して実行する典型的な実装戦略を持っています。 。

おそらく、編集プロセスが「重い」、ゆっくり、高セレモニーの焦点に焦点が当てられている可能性があります。 Cpythonは、できるだけ軽量で、できるだけ軽量で、儀式が実現可能であるため、できるだけ早くコンパイルするように設計されています。コンパイラはエラーチェックと最適化をほとんど行わないため、速くて少量のメモリで実行できます。ほとんどの場合、ユーザーがコンピレーションが行われていることに注意する必要さえなく、必要なときはいつでも自動的かつ透過的に実行されます。 JavaとC#は通常、エラーをより徹底的にチェックし、より多くの最適化を実行するために、コンピレーション中により多くの作業を受け入れます(したがって自動コンパイルを実行しない)。それは黒人や白人の状況ではなく、灰色のスケールの連続体であり、与えられたレベルにしきい値を置き、そのレベルを「コンパイル」と呼ぶだけであると言うのは完全にarbitrary意的です! - )

インタープリター言語などというものは存在しません。インタプリタを使用するかコンパイラを使用するかは、純粋にその言語の特性です。 実装 そして言語とはまったく関係がありません。

言語はインタプリタまたはコンパイラのいずれかによって実装できます。大多数の言語には、各タイプの実装が少なくとも 1 つあります。(たとえば、C と C++ にはインタープリターがあり、JavaScript、PHP、Perl、Python、Ruby にはコンパイラーがあります。) さらに、最新の言語実装の大部分は、実際にはインタープリターとコンパイラー (または複数のコンパイラー) の両方を組み合わせています。

言語は抽象的な数学的規則のセットにすぎません。インタプリタは、言語の具体的な実装戦略の 1 つです。これら 2 つはまったく異なる抽象レベルで生きています。英語が型付き言語である場合、「解釈された言語」という用語は型エラーになります。「Python はインタプリタ型言語である」というステートメントは、単に偽であるだけではなく (偽であるということは、たとえそれが間違っていたとしても、ステートメントが意味をなさないことを意味するからです)、明らかに意味がありません。 センス, 、言語はできるからです 一度もない 「解釈される」と定義されます。

特に、現在既存の Python 実装を見ると、次のような実装戦略が使用されています。

  • アイアンパイソン:DLR ツリーにコンパイルされ、その後 DLR が CIL バイトコードにコンパイルします。CIL バイトコードに何が起こるかは、どの CLI VES を実行しているかによって異なりますが、Microsoft .NET、GNU Portable.NET、および Novell Mono は最終的にネイティブ マシン コードにコンパイルします。
  • ジトン:ホット コード パスを特定するまで Python ソースコードを解釈し、ホット コード パスを JVML バイトコードにコンパイルします。JVML バイトコードに何が起こるかは、実行している JVM によって異なります。Maxine は、ホット コード パスを特定するまで、最適化されていないネイティブ コードに直接コンパイルし、その後、最適化されたネイティブ コードに再コンパイルします。HotSpot は、まず JVML バイトコードを解釈し、最終的にホット コード パスを最適化されたマシン コードにコンパイルします。
  • ピピ:PyPy バイトコードにコンパイルされ、ホット コード パスが特定されるまで PyPy VM によって解釈され、実行しているプラ​​ットフォームに応じてネイティブ コード、JVML バイトコード、または CIL バイトコードにコンパイルされます。
  • CPython:CPython バイトコードにコンパイルされ、それが解釈されます。
  • スタックレス Python:CPython バイトコードにコンパイルされ、それが解釈されます。
  • 荷物を積んでいないツバメ:CPython バイトコードにコンパイルし、ホット コード パスを特定するまで解釈して LLVM IR にコンパイルし、LLVM コンパイラがネイティブ マシン コードにコンパイルします。
  • サイソン:Python コードを移植可能な C コードにコンパイルし、その後標準 C コンパイラでコンパイルします。
  • ヌイツカ:Python コードをマシン依存の C++ コードにコンパイルし、その後標準 C コンパイラでコンパイルします。

このリストにあるすべての実装 (および、tinypy、Shedskin、Psyco など、私が言及しなかったその他の実装) にはコンパイラーがあることに気づくかもしれません。実際、私の知る限り、純粋に解釈される Python 実装は現在存在せず、そのような実装は計画されておらず、そのような実装はこれまでにありませんでした。

「解釈された言語」という用語が意味をなさないだけでなく、たとえ「解釈された実装を備えた言語」を意味すると解釈したとしても、それは明らかに真実ではありません。誰がそんなことを言ったとしても、彼が何を言っているのか分かっていないのは明らかです。

特に、 .pyc 表示されているファイルは、CPython、Stackless Python、または Unladen Swallow によって生成されたキャッシュされたバイトコード ファイルです。

これらは、a .py ファイルはインポートされており、インポートされたモジュール/プログラムの「コンパイルされたバイトコード」が含まれています。ソースコードからバイトコード(1回のみを実行する必要がある)への「変換」は、後続でスキップできるという考えです。 importsの場合 .pyc 対応するものよりも新しいです .py ファイル、したがって、スタートアップを少し高速化します。しかし、それはまだ解釈されています。

ロードモジュールをスピードアップするために、Pythonは.Pycのモジュールのコンテンツをコンパイルしたコンテンツをキャッシュします。

Cpythonはソースコードを「バイトコード」にコンパイルし、パフォーマンス上の理由で、ソースファイルに変更がある場合はいつでもファイルシステム上のこのバイトコードをキャッシュします。これにより、コンパイルフェーズをバイパスできるため、Pythonモジュールの負荷がはるかに高速になります。ソースファイルがfoo.pyの場合、cpythonはソースのすぐ横にあるfoo.pycファイルのバイトコードをキャッシュします。

Python3では、Pythonのインポート機械は、すべてのPythonパッケージディレクトリ内の単一のディレクトリ内のバイトコードキャッシュファイルを書き込み、検索するために拡張されています。このディレクトリは__Pycache__と呼ばれます。

これは、モジュールのロード方法を説明するフローチャートです。

enter image description here

詳細については:

参照:PEP3147
参照:「コンパイルされた」Pythonファイル

これは初心者向けです、

Pythonは、実行する前に、スクリプトを自動的にコンパイルして、バイトコードと呼ばれるコードをコンパイルします。

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

たとえば、スクリプトファイルがある場合 ABC.py それは別のモジュールをインポートします xyz.py, 、走るとき ABC.py, xyz.pyc XYZがインポートされているので作成されますが、ABC.Pycファイルは 作成した abc.pyが輸入されていないため。

インポートされていないモジュールの.PYCファイルを作成する必要がある場合は、 py_compilecompileall モジュール。

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ファイルは基本的にキャッシュのように扱われます。彼らは物事をスピードアップしますが、通常はそれらをまったく認識する必要はありません。ファイルの時間/日付スタンプに基づいて、必要に応じてそれらを自動的に無効にして再ロードします(ソースコードを再コンパイルします)。

私がこれで問題を見たのは、コンパイルされたByteCodeファイルが何らかの形でタイムスタンプを将来的に獲得したときだけでした。新しく見えたので、ソースファイルが再コンパイルされることはなかったので、どんな変更を加えても、それらは無視されました...

Pythonの *.pyファイルは、コードの行を記述するテキストファイルにすぎません。 「python filename.py」と言ってこのファイルを実行しようとするとき

このコマンドは、Python仮想マシンを呼び出します。 Python Virtual Machineには、「コンパイラ」と「インタープリター」の2つのコンポーネントがあります。通訳者は *.pyファイルでテキストを直接読み取ることができないため、このテキストは最初にPVMをターゲットにしたバイトコードに変換されます (ハードウェアではなくPVM). 。 PVMはこのバイトコードを実行します。 *.pycファイルも生成されます。これは、シェルまたは他のファイルでファイルでインポート操作を実行する実行の一部として生成されます。

この *.pycファイルが既に生成されている場合、次回 *.pyファイルを実行/実行するたびに、システムはコンパイルが必要ない *.pycファイルを直接読み込みます(プロセッサのマシンサイクルを節約します)。

*.pycファイルが生成されると、編集しない限り *.pyファイルは必要ありません。

Pythonコードは2つの段階を通過します。 First Stepは、実際にはBytecodeである.Pycファイルにコードをコンパイルします。次に、この.pycファイル(bytecode)は、cpythonインタープリターを使用して解釈されます。参照してください これ リンク。ここで、コードコンパイルと実行のプロセスについて簡単に説明します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top