こんにちは!エキサイトエンジニアのオノです。
Pythonを使用して開発する機会があったので、Pythonについてまとめてみました。
※「Python」の日本語訳は「ニシキヘビ」でアイコンには蛇が使用されています。
Pythonの歴史
Pythonの最初のバージョンは1991年にオランダのグイド・ヴァン・ロッサム(Guido van Rossum)氏によって発表されました。1991年のバージョン0.90以来オープンソースとして配布され、現在では「2.x」系、「3.x」系という2つのメジャーバージョンが併用されリリースされています。
Pythonの特徴
Pythonはシンプルな構文を特徴としています。これは初心者にとっては学習し易く、経験者にとっても効率的なプログラムの作成が可能です。ブロック構造(プログラムの区切り)に C言語や Java言語のような括弧{}を用いず、インデントを用いるため、誰が書いても似たようなプログラムになるという特徴があります。これは個人のプログラミングの癖を排除し、可読性を上げる働きがあります。文法もシンプルで必要最低限のものしか用意されていません。
多様なライブラリ
ライブラリが非常に多く、数学計算からデータベース、Web 開発、GUI アプリの作成まであらゆるプログラムを実現できます。ライブラリが豊富であるため、効率的なプログラミングが可能です。
学習・開発コスト
プログラミングに必要な開発環境は、公式サイトから無料でダウンロードできます。このため、プログラミングの学習や開発において扱いやすいです。
できること
- GUIアプリケーションの開発
独自で GUIアプリを作成する場合も、たった3行から GUIの開発を始めることができます。

- バックエンドの開発
豊富なフレームワークが提供されており、有名なところでは Djangoや Flaskなどがあります。
- 機械学習の実装
機械学習の実装にもよく使われています。データ処理のための数値計算のライブラリや、グラフ描画のためのライブラリなど機械学習関連のライブラリがとても充実しています。
バージョンの問題
「2.x」系バージョンと「3.x」系バージョンが併存しています。「3.x」系バージョンには、「2.x」系バージョンへの後方互換性がありません。どちらの系列を使用するかは、利用するライブラリの移行状況に依ります。
簡単なサンプル
#サンプル…1
import datetime…2
'''
現在日時を表示…3
'''
def todaytime():…4
now = datetime.datetime.now()
print now.strftime("%Y/%m/%d %H:%M:%S")
if __name__ == '__main__':…5
todaytime()
- ハッシュ(#)から行末まではコメントとみなされます。
- パッケージの中からモジュールや識別子(クラス、関数、変数...)をインポートできます。
- 「'」(シングルクォーテーション)もしくは「"」(ダブルクォーテーション)3つでコメントアウトとしたい部分を囲んでしまえば、それをあたかもコメントであるかのように扱うことができます。
- def 文を用いて関数(function)を定義することができます。
- __name__は現在のモジュール名を示します。スクリプトとして起動されたメインモジュールの場合は __main__ という名前が設定されます。コマンドラインから直接スクリプトファイルを実行した場合実行され、モジュールとしてimportした場合実行されません。
実装に関してはまったこと、調査したこと
文字コードの指定
マルチバイト文字列を扱うときは文字コードの宣言をする必要があります。utf-8にするときはファイルの先頭に以下の記述を追加します。
# -*- coding: utf-8 -*-
この1行がないだけで、実行できないことがたくさんありました。
並列処理(threadingとmultiprocessing)
並列処理を実装したく、threadingとmultiprocessingについて調べました。
threadingにはGIL問題があり、GIL(Global Interpreter Lock)とはPythonのインタプリタ上で一度に1つのスレッドだけが動作するよう保証するためのロックです。このロックによって、同時に同じメモリにアクセスするスレッドが存在しないことを保証します。ロックによって,一度に1つのスレッドしか実行されなくなるので、デュアルコアのCPUなどのリソースを最大限生かすことができなくなっています。そこで、プロセスを分けて、GIL問題を回避しようというのが、multiprocessingモジュールです。リスト1とリスト2は共に、10000000までカウントアップするプログラムです。リスト1はthreadingモジュール、リスト2はmultiprocessingモジュールで実装しています。また、プログラムの最後にそれぞれのカウントアップに要した時間を表示しています。
リスト1(threading)
# -*- coding: utf-8 -*-
from time import time
from threading import Thread
def f():
'''カウントアップ
'''
i = 0
while i > 10000000:
i = i + 1
def ThreadTest():
lst = []
# スレッドの生成
for i in range(4):
lst.append( Thread(target=f) )
start = time()
# スレッドの開始
for t in lst:
t.start()
# スレッドが終了するまで待つ
for t in lst:
t.join()
finish = time()
print('threding:', finish - start)
if __name__ == '__main__':
ThreadTest()
リスト2(multiprocessing)
# -*- coding: utf-8 -*-
from time import time
from multiprocessing import Process
def f():
'''カウントアップ
'''
i = 0
while i > 10000000:
i = i + 1
def ProcessTest():
lst = []
# プロセスの生成
for i in range(4):
lst.append( Process(target=f) )
start = time()
# プロセスで実行
for t in lst:
t.start()
# プロセスが終了するまで待つ
for t in lst:
t.join()
finish = time()
print('multiprocessing:', finish - start)
if __name__ == '__main__':
ProcessTest()
デュアルコアのCPUを乗せたマシンでの実行結果、リスト1を実行した際にはCPUの利用率が100%まで行かず、CPUリソースを100%使いきっていませんでした。また、リスト2を実行した際にはCPUの利用率が100%まで行っており、CPUを有効に使っていました。その他、threading版はmultiprocessing版の2倍以上の時間差があることから、PythonのインタプリタではGILの取得にかかるコストが大きいことがわかります。サンプルの作成して調査したのですが、実装には並列処理を実装しなくてもよくなりthreadingのtimerを実装しただけとなりました。
ユニットテスト
今回Pythonでのユニットテストはunittestというそのままな名前のモジュールを使いました。
テスト用のクラスの中で以下に記載されるようなメソッドを使ってプログラムが期待どおりの「返り値」を持っているか、挙動を行うかを確認します。
- assertEqual()
- assertTrue()
- assertIs()
- assertRaise()
このほかにもいろいろあるのですが、assertRaise以外のものはそれほど難しくなく、assertEqualは同一か、assertTrueはTrueか、assertIsはIS関係かどうかといったことをチェックします。assertRaiseは「期待どおりに例外が発生するか」を調べるものです。
モジュールもありテストも簡単に実行できましたが、テストケースを作成するのに戸惑って、これはどんな言語を使用しても変わらないことを痛感しました。
開発で使用してみた感想
人気があるのでドキュメントも日本語でしっかり存在し、情報も豊富にあります。わかりやすく、読みやすい言語で開発も大きな問題もなく順調に進めることができました。
マイナーな言語ではなく、機能追加も容易にできること、この2点から今回開発にPythonを選びました。
開発内容はGUIアプリケーションではなかったので、機会があればGUIの開発をしてみたいと思いました。また、開発中に検索したサンプルで機械学習を多く扱っていたので、業務で試してみたいとも思いました。
エンジニア募集
エキサイトではエンジニアとして一緒に働いてくださる方を新卒採用と中途採用で募集しています。詳しくは、
こちらの採用情報ページをご覧ください。