今までPythonに関してさまざまなことを学んできたので、簡単なプログラムやアプリケーションは作ることができるようになったと思います。今回はそれらを配布する方法について扱います。

Pythonプログラムの実行方式

Pythonのプログラムの配布方式の説明の前に、まずはコンパイラとインタプリタの違いについて知ってもらう必要があります。

本連載の冒頭にも言いましたが、コンピュータが理解できるのは突き詰めると、0と1だけです。そのため、プログラムを実行するには「プログラミング言語で書かれたテキストのプログラム」を0と1に変換する必要があります。そのやり方には2つあり、ひとつはコンパイラを使うもので、もうひとつはインタプリタを使うものです。

以下に両者の違いについて記載します。

コンパイラとインタプリタの違い

まず、コンパイラを使う場合ですが、これは「テキストのプログラムをまず0、1のバイナリファイルに変換し、そのファイルを実行する」という動き方をします。まず最初に完全に変換し、そのあとでそれを実行するという形です。

一方、インタプリタ型はコンパイラのように先に変換してしまうのではなく「プログラムの実行時に、テキストで書かれたプログラムを都度0、1に変換しながら実行する」という動き方をします。つまり一気に変換してしまうのではなく、実行しながら今必要な箇所を0、1に変換しながら動いています。図にあるように、Pythonはインタプリタ型のプログラミング言語です。

プログラムの配布と実行方法

さて、インタプリタ型のプログラムを実行するには「都度0、1に変換する」必要があるのでした。これはつまり、プログラムの実行にはプログラムファイルのほかに「0、1に変換するインタプリタ」が必要ということです。以下の図を見てください。

インタプリタが載っていないマシンではスクリプトを解釈できない

あるPythonスクリプト(プログラム)を配布する際、そのスクリプトを実行できるインタプリタがあるマシンだと、そのマシンが持つインタプリタでスクリプトを解釈して実行することができます。ただ、インタプリタが載っていないマシンではスクリプトは解釈することができません。この場合、プログラムではなく単なるテキストにすぎないので、当然ながら実行することはできません。

要するに、Pythonのプログラムをスクリプトとして配る際には「このPythonのプログラムを動かすにはPythonをインストールしておいてくださいね」と暗黙的に言われているというということです。

次にコンパイラ型言語で作られたプログラムの配布方法ですが、これはもっと簡単です。以下の図を見てください。

コンパイラ型言語で作られたプログラムの配布方法

まず、配布されるプログラムは、配られる時点ですでにバイナリ(0、1形式のファイル)になっています。そのため、基本的に配布されたプログラムはそのバイナリファイルを動かせるOSであれば、インタプリタがなくても動かすことができます。つまり、OSさえ正しければ、どのマシンでも動かすことができるわけです(正確に言うとハードウェアにも依存しますが、組み込みなどでなければ普通は気にならないです)。

なお、JavaはJVM(Java Virtual Machine)があるため少し特殊ですが、少なくともインタプリタ型とは言われません。あえて言うのであれば「Java実行環境は必ずある」という前提をおいてコンパイラ型に分類される気がします。

Python Scriptのバイナリ化

ここまでの説明を読んだら、Pythonのプログラムをどのように配布すれば誰でも使えるようになるかわかりましたよね。そうです、スクリプトを「バイナリ化」してから配布すればいいのです。このイメージ図を以下に記載します。

スクリプトをバイナリ化してから配布する

Pythonのスクリプトをバイナリ化すると、Pythonインタプリタをインストールしていないマシンでもプログラムが実行可能になります。

バイナリ化を行うツールは、そのバイナリの対象OSごとにあり、Windowsの場合はpy2exeなどを使い、Macなどの場合はpy2appを使います。これ以外にもバイナリ化のツールにはいろいろありますので、自分の好きなものを使っていただければと思います。

Pythonスクリプトのバイナリ化

ツールのインストールの準備

今回はpy2appをMacに、py2exeをWindowsにインストールします。そのインストール作業に「pip」と呼ばれるPythonのパッケージ管理ツールを利用するので、まずはじめにpipの準備をします。なお、今回はWindowsでは利用しないので、Windowsの人は読み飛ばしていただいてかまいません。ただ、pipの使い方は知っておいていただいたほうがよいです。

pipのインストール前に、一応すでにpipが入っていないか確認します。

% pip --version
pip 1.5.6 from /Library/Frameworks/Python.framework/Versions/2.7/lib/pyth    on2.7/site-packages (python 2.7)

すでに入っていれば上記のようにpipのバージョンが表示されるはずです。この場合は改めてインストールをする必要はありません。エラーが出れば、まだインストールされていないものと思われます(もしくはパスが通っていないか)。

pipのインストールは最近非常に簡単になっており、get-pip.pyというプログラムをダウンロードしてきて、それを実行するだけになったようです。ダウンロードリンクはいくつかあるようですが、以下のものが有名なようです。リンク切れなどをしていたら調べて、別の箇所からダウンロードしてください。

https://bootstrap.pypa.io/get-pip.py

これをダウンロードし、Pythonで実行します。

python get-pip.py

これでpipのインストールは完了です。

Macアプリケーションのバイナリ化

pipをインストールしたので、py2appをMacにインストールします。

その前に、今回バイナリ化するサンプルプログラムを作成しておきます。以前お話したTkinterを使ったGUIのプログラムです。プログラムの細かい話は今回は割愛します。ファイル名はmyapp.pyとしています。

import Tkinter

counter = 0
font = ("Helevetica", 32, "bold")
button = Tkinter.Button(font=font, text=str(counter))

def clicked():
    global counter, button
    counter = counter + 1
    button.config(text=str(counter))

button.config(command=clicked)
button.pack()
button.mainloop()

さて、このプログラムを起動するにはターミナルを開いて、

% python myapp.py

などというようにpythonコマンドでプログラムのファイルを呼び出すのでした。すると以下のようなアプリが起ちあがります。

起動するアプリのイメージ

逆に言えばpythonコマンドがインストールされていないと起動することができません。このプログラムをバイナリ化してみます。

まずはpy2appのインストールです。これには先ほどのpipを利用します。Linuxのパッケージ管理ツールとよく似た使い方ですね。

% sudo pip install -U py2app
Password:
Requirement already up-to-date: py2app in /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/py2app-0.9-py2.7.egg
...
Successfully installed modulegraph
Cleaning up...
%

インストールできたので、いよいよpy2appを使ったバイナリ化をします。バイナリ化の流れは、

  1. バイナリ化するための設定ファイルsetup.pyのテンプレートを作成
  2. setup.pyを編集
  3. setup.pyを実行

となります。

順に見ていきましょう。まずテンプレートの作成ですが、これは以下のように行います。

% py2applet --make-setup myapp.py
Wrote setup.py

オプションでsetupを作ることと、その対象となるプログラムを指定しています。これを実行するとmyappをバイナリ化するための設定ファイルであるsetup.pyが作成されているはずです。その中身を見てみます。

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['myapp.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

これを必要に応じて編集します。編集の詳細はpy2appのページなどで確認してください。

今回は編集なしのデフォルトのままでバイナリ化したいと思います。バイナリ化するにはこのsetup.pyを実行します。

% python setup.py py2app

必要に応じてsudoを付けて下さい

% sudo python setup.py py2app

するとdistというディレクトリが作成され、その中にmyappというアプリケーションが作成されました。試しにダブルクリックしてみると先ほど作ったアプリケーションが起動するはずです。

ダブルクリックでカウンターアプリが起動

このmyappはバイナリファイルですので、これをほかのMacに配ってもそこで起動することができます。ただ、Mac用のバイナリなので、当然ながらWindowsでは使えません。

Windowsアプリケーションのバイナリ化

Windowsのpythonアプリケーションのバイナリ化にはpy2exeを使います。

http://www.py2exe.org/

使い方はほとんど同じなのですが、インストールはpipではなくファイルをダウンロードしてインストールします。pipだとversion 3向けのパッケージをインストールしてしまうようです。

ファイルをダウンロードしてインストール

ダウンロードは上記ページにあるsourceforgeのダウンロードページから行うことができます。自分が使っているversionにあわせたインストールファイルを選択してインストールを行ってください。

次にpy2appと同様にsetup.pyを準備します。ただ、py2exeではテンプレート作成機能はないようなので、自分で作成します。

from distutils.core import setup
import py2exe

setup(console=['myapp.py'])

このsetupファイルを使って、先ほどのMacで使ったプログラムmyappをバイナリ化します。バイナリのアプリケーションはpy2appと同じくdistフォルダに作成されます。

python setup.py py2exe

ダブルクリックで起動

こちらもアプリケーションをダブルクリックすることで起動できます。distの下にファイルがたくさんありますが、これは必要なファイルなので、distフォルダごとまとめて配布する必要があります。

バイナリファイルの中身

最後にpy2appで作成したアプリケーションmyappの中身を確認してみます。

myappの中身

さまざまなファイルからアプリケーションが構成されていることがわかりましたが、そのなかに「もとのスクリプトファイル」とPythonそのものが入っていることがわかります。

バイナリ化したといっても、スクリプトとそれを動かすPythonをセットにして配布しているだけです。Cのバイナリファイルとは根本的に仕組みが違うので注意してください。


オブジェクト指向までで本連載の主要な内容はすべて扱いました。次回からは例外処理など、まだ説明していない重要な内容について順に扱っていきます。

執筆者紹介

伊藤裕一(ITO Yuichi)

シスコシステムズでの業務と大学での研究活動でコンピュータネットワークに6年関わる。専門はL2/L3 Switching とデータセンター関連技術およびSDN。TACとしてシスコ顧客のテクニカルサポート業務に従事。社内向けのソフトウェア関連のトレーニングおよびデータセンタとSDN関係の外部講演なども行う。

もともと仮想ネットワーク関連技術の研究開発に従事していたこともあり、ネットワークだけでなくプログラミングやLinux関連技術にも精通。Cisco社内外向けのトラブルシューティングツールの開発や、趣味で音声合成処理のアプリケーションやサービスを開発。

Cisco CCIE R&S, Red Hat Certified Engineer, Oracle Java Gold,2009年度 IPA 未踏プロジェクト採択

詳細(英語)はこちら