Python のメリット

すでに php を覚えているのに、わざわざ Python を覚えるメリットは何でしょうか? この章では Python の魅力の一端を紹介します。

汎用言語

Python は汎用言語で、データ解析、自然言語処理、ゲーム、デスクトップアプリなどを 作るのに広く使われており、ライブラリも充実しています。

一方、 Web に特化していないため、例えばセッションの保存場所は python.ini に書くことはできず、アプリケーション側で面倒をみないといけません。 その点では、 php などの特定の用途に特化した言語に比べると、若干取っ掛かりにくい 場合があります。

それでも、いろんなことに挑戦するときに、構文や基本的なお約束ごとなどを一から 覚えなおさないで済むのは大きな利点です。

いろんな並行モデルに対応している

例えば複数のHTTPリクエストを並行して実行したい場合、OSのプロセスやスレッドを 使ったり、イベントドリブンで書いたり、言語内で用意されている軽量スレッドを 利用したりする方法が考えられます。

どの方法も長所と短所があるのですが、 Python は上で挙げたすべての方式に 対応できるので、いろんな場面で最適な選択肢を取ることができます。

シンプルで覚えやすい

Python の構文は、よく使われているプログラム言語の中では比較的シンプルです。 例えば、 php と比べると、参照も、 private/protected も、 interface も言語としては 持っていません。

また、似たような操作を汎用化することで違う型のオブジェクトでも同じ書き方が できるので、とても覚えやすいです。いくつか例を挙げます。

>>> s = "foo"   # 文字列
>>> a = [1,2,3] # list (配列) 型
>>> d = {'key1': 'val1', 'key2': 'val2'} # dict (key-value) 型

# 要素数のカウント
>>> len(s)
3
>>> len(a)
3
>>> len(d)
2

>>> 'oo' in s   # 部分文字列のチェック
True
>>> 2 in a      # 要素として含むかどうかのチェック
True
>>> 'key1' in d # dict の場合は key についてチェック
True

# 添字によるアクセス
>>> s[0]
'f'
>>> a[0]
1
>>> d['key1']
'val1'

# ループ
>>> for i in s:
...     print(i)
...
f
o
o
>>> for i in a:
...     print(i)
...
1
2
3
>>> for i in d:
...     print(i)
...
key2
key1

読みやすい

Python は、読みやすく、簡潔で、効率も良いコードの書き方を Pythonic と読んで推奨しています。 ある程度 Python に慣れた人が書いたコードは、癖がなく、誰にとっても読みやすくてメンテナンスしやすい ようになっています。

また、標準のコーディング規約も早いうちに整備されていて、ほとんどのライブラリが それに従っています。インデントやスペースの位置で宗教論争することも、プロジェクトごとに コーディング規約が違うこともありません。

リーダビリティを定量的に評価することは難しいですが、多くの人が Python は読みやすい言語だと 評価しています。

エラーを隠さない

Python の基本方針として、エラーかもしれない場合はそれを隠すのではなく積極的に 例外を発生させるというものがあります。

プログラムが大規模化していると、タイプミスなどのイージーミスが、結果として 全然違う場所で意味不明な問題を引き起こし、その解析に苦労することがあります。

未初期化変数へのアクセスなどのエラーを早い段階で検出しスタックトレースを出力 することで、無駄な時間を大幅に削減することができます。

インタラクティブシェル

最近は多くの言語がインタラクティブシェル (REPL: read-eval-print loop とも言う) を持っていますが、 Python では特に重視されています。インタラクティブシェルを 日常的に使うようになると、初めて触るライブラリや慣れないフレームワークでも 1行ごとにその場で実行結果を見ながらプログラムを書くことができるので、学習コストを 下げることができます。

また、多くの Web フレームワークがデバッグモード時に例外が発生したらブラウザ上に インタラクティブシェルを表示する機能を持っています。 エラーが起こってからログを仕込んでバグが再現するまで再実行する必要が無いので、 デバッグが非常に効率的になります。

動的言語

php は動的型付け言語ですが、クラス定義などは Java の影響が強く、あとから定義を差し替えたり、 定義をフックする処理をするのが難しいです。そのためにコードジェネレーターを書かないと いけないこともあります。

Python は php よりも動的な部分が多いので、テストの時に一部の関数をモックに置き換えるとか、 コードジェネレーターの代わりに定型的なコードを抽象化する仕組みを使うことができます。

C言語と仲がいい

Python は拡張モジュールの作成をサポートするツールが豊富で、手軽に他のC/C++の ライブラリと連携したり、一部の処理を高速化することができます。 例として、素数を計算する関数を高速化してみましょう。

def primes(n):
    primes = []
    i = 1
    while len(primes) < n:
        i += 1
        for x in primes:
            if i%x == 0:
                break
        else:
            primes.append(i)
    return primes

この関数で primes(20000) を実行するのに17秒かかりました。 これを Cython というツールで高速化してみます。そのままコンパイルするだけでも 数割速くなるのですが、少しヒントを与えると大幅な高速化が可能です。

def primes(int n):
    cdef int i, x
    primes = []
    i = 1
    while len(primes) < n:
        i += 1
        for x in primes:
            if i%x == 0:
                break
        else:
            primes.append(i)
    return primes

これで、 primes(20000) が2秒になりました。このコードでもまだ大きな無駄が あるのでもっと高速化することができますが、ここではここまでにしておきます。

速度

拡張モジュールでプログラムの実行時間を短くするのが簡単という以外にも、 速度のメリットがあります。

Web アプリでは、 Python はリクエストごとに1から起動する処理をしなくても済むので、 フレームワークや設定ファイル、モデルなどが肥大化しても、応答速度への影響が ほとんどありません。

また、コマンドラインツールの場合は毎回1から起動することになるのですが、バイト コードキャッシュ (php では APC に相当するもの) が使えるので、たくさんライブラリを 利用するツールでも比較的サクサクと起動することができます。