Pythonでコンパイルは可能なのか?やり方をまとめてみた


Pythonでコンパイルは可能なのか?やり方をまとめてみた

自分でつくったPythonコードを秘密にしたい。
Pythonプログラム、C言語なみに早く実行したい。
そんなとき「コンパイル」が役立つかもしれません。
PythonもJavaやC++のようにコンパイルすることが可能ですよ。

目次
  1. Pythonでコンパイルは可能なのか?やり方をまとめてみた
  2. Pythonファイルをコンパイル
  3. 自動的にコンパイル
  4. Pythonプログラムの処理フロー
  5. コンパイルのメリット・デメリット
  6. Pythonの標準以外のコンパイル方法
  7. Pythonのいろいろな実装方法
  8. まとめ
  9. おまけ スピードテスト

Pythonでコンパイルは可能なのか?やり方をまとめてみた

Pythonファイルをコンパイル

image

Pythonプログラムには、標準でコンパイル関数の py_compile() が用意されています。 例えば、

print('コンパイルだよ')

というコードを hello.py で保存。

次にターミナルもしくはコマンドを hello.py と同じディレクトリで開きます。

そして

>>> python
>>> import py_compile
>>> py_compile.compile('hello.py')

とすると

'__pycache__/hello.cpython-36.pyc'

が生成されます。

image

image

一旦 Pythonスクリプトを終了し、

cd __pycache__
python hello.cpython-36.pyc

と入力すると、

コンパイルだよ

と出力されます。

image

なんとPythonは .py 以外に、Pythonコードをコンパイルした .pyc というファイルも実行できるんですね。

それで次に hello.py はエディタで開けますが、 hello.cpython-36.pyc はどうでしょうか? いつも使っているエディタでは開けませんので、ターミナルから

vi hello.cpython-36.pyc

とすると、読めないファイルに。 Pythonファイルがコンパイルされていることが分かりますね。

image

自動的にコンパイル

image

Python学習を進められている方の中には、 __pycache__ というフォルダに見覚えがある方もいらっしゃるかもしれません。 この __pycache__ というフォルダ、実はモジュールを実行した時、自動的に生成されます。 試しに簡単なモジュールを作成して、実行してみましょう。

【ファイル名 main.py】

from module import tool

tool()

【ファイル名 module.py】

def tool():
    print('モジュール')

【コマンド】

python main.py

<< 実行結果 >>

image

なんと自動的に __pycache__ フォルダ内が作成されて、その中に module.py のコンパイルされたファイルが保存されています。 これはPythonプログラム内で import を使った時に自動操作されていることで、よく import する numpy や Beautiful Soup など各ライブラリにも __pycache__ フォルダは存在し、使う度に更新。 どんな状態になっているか興味ある方は、pip show numpy などでライブラリのある場所を確認して、フォルダを覗いてみて下さい。

【.pyc について】
ファイルサイズこそ大きくないにしても、 「.pyc も pycacheフォルダ も消したい」と思うこともあるでしょう。大丈夫です、消してもPythonプログラムを実行するとまた .pyc も pycache も自動的に作成されます。

Pythonプログラムの処理フロー

image

Pythonプログラムでモジュールを利用する時のコンパイルフローを上記に示します。

実際に、プログラムを書き換えて実行してみると、コンパイルファイルも自動更新されますので試してみて下さい。

コンパイルのメリット・デメリット

image

【メリット】

  • プログラムの実行速度が早くなることもある
  • Pythonコードを秘密にできる
  • コンパイル方法を変えると Java や C# とも共存できる

【デメリット】

  • 内容がややこしい
  • 処理速度が早くならないこともある

Java や C++ などはコンパイルが必須ですが、Pythonは基本コンパイル不要で動作。 ただそれは自分たちの知らない間にコンパイルしていただけの話。

コンパイルを標準の CPython 以外に PyPy や Jython などにすると、処理速度が早くなったり Java と Pythonが共存できたりなど標準以上の機能に期待できます。

Pythonの標準以外のコンパイル方法

image

Pythonの標準コンパイル方法は、 CPython。

これよりも実行速度が早いと言われるコンパイル方法が、 PyPy。

他の言語との共存を可能にする方法が、Jython や IronPython、PythonNet など。

これらのツールは、Pythonの基礎学習用参考書には載っていなく、上級者向けの内容と考えられます。アプリケーション開発などを行う方は、PyPy などを知っておくといいかもしれませんね。

【PyPyのサンプル】

pypy hello.py

PCにPyPyをインストールした後は、Python ●●.pyの代わりに pypy ●●.py と命令文が変わるだけです。

image

また __pycache__ フォルダの中には、 ●●.pypy3-24.pyc というような形式でコンパイル済みのファイルが自動生成。

Pythonのいろいろな実装方法

image

画像引用:IronPython

先ほど登場した PyPy など標準外のPythonの実行方法をご紹介します。参考程度に閲覧下さい。

CPython

Pythonに標準で備わっているソフトで、最も広く使われている実装方法。C言語で書かれ、C拡張モジュールと高い互換性を示します。

PyPy

PyPyは、CPythonと高い互換性を示しつつ、より高いパフォーマンスの実現に期待できるソフトです。場合によっては、CPythonより 5倍以上高いパフォーマンス*を示した例もありますね。

IronPython

IronPythonは、Windows の Visual Studio でPythonを使う場合の実装方法で、 .NET フレームワーク・ライブラリと Pythonライブラリの両方を使うことが可能。Windowsのコアユーザーは、知っておきたい実装方法の一つかもしれませんね。

PythonNet

PythonNetは、Windows以外のOSXやLinuxユーザーで .NET フレームワークを使っている方向けの実装方法の一つです。

Jython

Jythonは、PythonファイルとJavaファイルの両方を使えるようにする実装方法。 例えば、JavaのクラスをPython内で実行など。 ちょっと頭が混乱しそうですが、システム上 Java が必要なときなどに有効。実行コマンドは、

jython hello.py

など。

image

まとめ

Pythonって標準でもWebやデスクトップアプリ、IoT など幅広いジャンルで利用できるのに、実装方法を変えるともっと広範囲で使えるって、スゴイですね。Pythonの「コンパイル」以前に、Pythonの基礎やコンパイルの基礎がまだという方、CodeCampで Python もしくは Java の勉強を始めてみませんか? オンライン × マンツーマンの CodeCamp ならスムーズにプログラミング・スキルを獲得できると思いますよ。

AIエンジニアに必要なスキルが身に付く

無料カウンセリングはこちら

おまけ スピードテスト

Pythonのコンパイルは、実効速度を早くするために行うもの。またPyPyという実行方法は、Python以上に早いとか。 簡単なプログラムで実行速度を測ってみました。

【コンパイル・ファイルなし no_m.py】

import time
t1 = time.time() 

for i in range(9999999):
    s = i**31
print(s)

t2 = time.time()
done_speed = t2-t1
print("処理時間:", done_speed)

image

【py_compile()によるコンパイルで実行】

image

【モジュール実行によるCPython自動生成で】

image

【PyPy】

image

<< まとめ >>

実行方法 タイム(秒)
python no_m.py 7.09
python no_m.cpython.pyc 5.36
python main.py 4.9
pypy3 main.py 8.19

Qiita などを参考に他の方のスピードテストを拝見すると、実行するプログラムによって PyPy の方が早かったり、遅かったりとまちまちな様子。今回私が試したループ処理も PyPy の方が遅く、あえてややこしいシステムを積極的に習う必要はない、と感じました。ただし、モジュールなしの no_m.py については、コンパイルファイル no_m.cpython.pyc を実行した方が早い結果になっています。こちらについてはコンパイルの恩恵を受けているといえますね。


オシママサラ
この記事を書いた人
オシママサラ
まずは7日間お試し!人気プログラミング講座を無料公開中
オンライン・プログラミングレッスンNo.1のCodeCamp