web-dev-qa-db-ja.com

Pythonを解釈すると、.pycファイルとは何ですか?

私は、Pythonがインタプリタ言語であることを理解するように与えられています...しかし、私のPythonソースコードを見ると、.pycファイルがあります。これらはどこに入ってくるのですか?

932
froadie

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

Pythonのドキュメントでは、このような定義について説明しています。

Pythonはコンパイルされた言語とは対照的にインタプリタ型言語ですが、バイトコードコンパイラが存在するために区別があいまいになることがあります。つまり、実行可能ファイルを明示的に作成しなくてもソースファイルを直接実行できるということです。

587
unwind

Pythonはインタープリター言語であることを理解するために与えられました...

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

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

聖書のtypical印刷が実際にハードカバー製本になっている可能性はかなりあります-結局のところ、それは通常読み返されることを意図した本でありいくつかの場所でブックマークを付け、与えられた章と詩のポインターなどを探して親指を立てて、優れたハードカバーバインディングは、そのような使用の下で与えられたコピーをより長く持続させることができます。ただし、これらはありふれた(実用的な)問題であり、特定の実際の書籍オブジェクトが聖書のコピーであるかどうかを判断するのには使用できません。ペーパーバック印刷は完全に可能です。

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

従来の実装であるCPythonは、単に「Python」と呼ばれることがよくありますが、MicrosoftのIronPython(CLRコード、つまり「.NET」にコンパイルされる)Jythonと並んで、いくつかの製品品質の実装の1つにすぎません。 (JVMコードにコンパイル)、PyPy(Python自体で記述され、「ジャストインタイム」生成されたマシン言語を含む非常に多様な「バックエンド」形式にコンパイルできます)。それらはすべてPython(== "Python言語の実装")であり、多くの表面的に異なる本オブジェクトがすべて聖書(== "聖書のコピー")になり得るように。

特にCPythonに興味がある場合:ソースファイルをPython固有の下位レベルのフォーム(「バイトコード」として知られる)にコンパイルし、必要に応じて(ソースファイルに対応するバイトコードファイルがない場合)、またはバイトコードファイルはソースよりも古いか、異なるPythonバージョンでコンパイルされています)、通常、バイトコードファイルをディスクに保存します(将来の再コンパイルを避けるため)。 OTOH IronPythonは通常、CLRコード(ディスクに保存するかどうかによって異なります)およびJythonをJVMコード(ディスクに保存するかどうかに応じてコンパイルします。保存する場合は.class拡張を使用します)。

これらの低レベルのフォームは、「インタープリター」とも呼ばれる適切な「仮想マシン」、CPython VM、.Netランタイム、Java VM(別名JVM)、適切に。

したがって、この意味で(典型的な実装は何をするのか)、C#とPythonが以下の場合に限り、Javaは「解釈言語」です。最初にバイトコードを生成してから、VM /インタープリターを介して実行します。

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

926
Alex Martelli

インタプリタ言語のようなものはありません。インタプリタとコンパイラのどちらが使用されているかは、純粋に implementation の特性であり、この言語とはまったく関係がありません。

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

言語は単なる抽象的な数学的な規則の集まりです。インタプリタは、言語のいくつかの具体的な実装戦略の1つです。この2人はまったく異なる抽象レベルで暮らしています。英語が型付き言語の場合、「通訳言語」という用語は型間違いとなります。 「Pythonはインタープリター言語です」という文は、単に間違っているわけではなく(間違っていても文が意味を成すことを意味するので)、単なる sense にはなりません。言語は 決して と解釈されることはできません。

特に、現在存在しているPythonの実装を見れば、これらが使用している実装戦略です。

  • IronPython:DLRがCILバイトコードにコンパイルするDLRツリーにコンパイルします。 CILバイトコードの動作は、実行しているCLI VESによって異なりますが、Microsoft .NET、GNU Portable.NET、およびNovell Monoによって、最終的にネイティブのマシンコードにコンパイルされます。
  • Jython:それがホットコードパスを識別するまでPythonソースコードを解釈し、それがJVMLバイトコードにコンパイルされます。 JVMLバイトコードがどうなるかは、実行しているJVMによって異なります。 Maxineはホットコードパスを特定するまで最適化されていないネイティブコードに直接コンパイルし、それから最適化されたネイティブコードに再コンパイルします。 HotSpotは最初にJVMLバイトコードを解釈し、そして最後にホットコードパスを最適化されたマシンコードにコンパイルします。
  • PyPy:PyPyバイトコードにコンパイルします。これは、実行しているプラ​​ットフォームに応じてネイティブコード、JVMLバイトコード、またはCILバイトコードにコンパイルされるホットコードパスを特定するまでPyPy VMによって解釈されます。
  • CPython:CPythonバイトコードにコンパイルされてから解釈されます。
  • Stackless Python:CPythonのバイトコードにコンパイルし、それを解釈します。
  • Unladen Swallow:CPythonバイトコードにコンパイルされ、次にホットコードパスがLLVM IRにコンパイルされ、LLVMコンパイラがネイティブマシンコードにコンパイルされるまで、それが解釈されます。

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

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

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

143
Jörg W Mittag

これらは.pyファイルがインポートされたときにPythonインタプリタによって作成され、インポートされたモジュール/プログラムの「コンパイルされたバイトコード」を含みます。 .pycが対応する.pyファイルよりも新しい場合は、後続のimportをスキップすることができるため、起動が少し速くなります。しかし、それはまだ解釈されています。

59
Tim Pietzcker

モジュールのロードを高速化するために、Pythonはコンパイルされたモジュールの内容を.pycにキャッシュします。

CPythonは、そのソースコードを「バイトコード」にコンパイルし、パフォーマンス上の理由から、ソースファイルに変更があるたびにこのバイトコードをファイルシステムにキャッシュします。これにより、コンパイル段階を回避できるため、Pythonモジュールのロードがはるかに速くなります。ソースファイルがfoo.pyの場合、CPythonはバイトコードをソースのすぐ隣のfoo.pycファイルにキャッシュします。

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

これはモジュールがどのようにロードされるかを記述するフローチャートです:

enter image description here

詳細については:

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

36
hxysayhi

初心者のためのTHIS IS、

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

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

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

インポートされていないモジュール用の.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にあるすべてのものをコンパイルします。

35
MAX

Python(少なくともその最も一般的な実装)は、元のソースをバイトコードにコンパイルし、次に仮想マシン上でそのバイトコードを解釈するというパターンに従います。これは(ここでも、最も一般的な実装)純粋なインタプリタでも純粋なコンパイラでもないことを意味します。

これの反対側は、しかしながら、コンパイルプロセスがほとんど隠されているということです - .pycファイルは基本的にキャッシュのように扱われます。それらは物事をスピードアップします、しかし、あなたは通常それらをまったく気にする必要はありません。ファイルのタイムスタンプに基づいて、必要に応じて自動的に無効化して再ロードします(ソースコードを再コンパイルします)。

私がこれに関して問題を見たのは、コンパイルされたバイトコードファイルがどういうわけか未来にタイムスタンプを持っていた時だけでした。見た目が新しくなったので、ソースファイルは再コンパイルされなかったので、どんな変更を行っても無視されました...

20
Jerry Coffin

Pythonの* .pyファイルは単なるテキストファイルで、その中にいくつかのコード行を書きます。 say "python filename.py"を使用してこのファイルを実行しようとしたとき

このコマンドはPython仮想マシンを起動します。 Python仮想マシンには、「コンパイラ」と「インタプリタ」の2つのコンポーネントがあります。インタプリタは* .pyファイルのテキストを直接読むことができないので、このテキストはまずPVM (ハードウェアではなくPVM) を対象とするバイトコードに変換されます。 PVMはこのバイトコードを実行します。 * .pycファイルは、Shellのファイルまたは他のファイルでインポート操作を実行するファイルの実行の一部としても生成されます。

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

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

11
Vishal Mopari

Pythonコードは2段階に分けられます。最初のステップでは、実際にバイトコードである.pycファイルにコードをコンパイルします。それから、この.pycファイル(バイトコード)はCPythonインタプリタを使って解釈されます。 this linkを参照してください。ここでは、コードのコンパイルと実行のプロセスについて簡単に説明しています。

7
Tango