Pythonの基礎
この節では、簡単にプログラミング言語としてのPythonについておさらいをしたいと思います。 Pythonは、プログラミング言語の中でもスクリプト言語、動的言語(Dynamic Language)に分類される言語です。同じスクリプト言語の仲間「Ruby」、「Perl」、「PHP」などと並んで軽量言語(LL、Lightweight Language)と呼ばれることもあります。
ノリがよく、手軽にプログラムの開発を行えるのがPythonのような軽量言語の特徴です。CやC++、Javaといったプログラミング言語に比べ、少ない時間でプログラムを開発できると言われています。プログラムの修正も容易です。
Pythonを使えば、Webアプリケーションで頻繁に扱う文字列データを手軽に扱うことができます。モジュールと呼ばれる機能を活用すれば、いろいろな処理を手軽に行えます。PythonはWebアプリケーションを作るのに向いたプログラミング言語だと言えます。
Pythonの起動
では実際にPythonを使ってみましょう。ここではインタラクティブシェル(対話型シェル)と呼ばれる機能を使ってPythonに触れてみます。インタラクティブシェルを使うと、Pythonを直接操作しながらプログラムを組むことができます。
WindowsにPythonをインストールすると、スタートメニューにPythonの項目が登録されます。この中にある【Python(command line)】という項目を選ぶと、Pythonのインタラクティブシェルを起動できます。
図03 Windowsのインタラクティブシェル
MacOS XやLinuxでは、シェルを使ってPythonを起動します。pythonというコマンドを入力して「Enter」キーを押すと、起動メッセージとともにPythonが起動します。
図04 Mac OS XやLinuxではシェルを使ってPythonを起動
ンタラクティブシェルを使って、簡単なPythonのプログラムを試してみましょう。>>>という文字列はプロンプトと呼ばれています。この文字列は入力する必要がありません。
Pythonを使うと数値だけでなく、ダブルクオーテーションで囲んだ文字列を簡単に扱えます。計算や処理の結果はインタラクティブシェルが自動的に表示しています。
:::python
>>> 1 + 1 # 足し算
2
>>> mach = 1225 # 音速(km/h)を変数に代入
>>> topspeed = 8600 # サターンVの最高速度
>>> topspeed / mach # 音速に換算
7.020408163265306
>>> language = "Python" # 文字列を変数に代入 # 文字列の足し算
>>> language + "はすばらしい!"
Pythonはすばらしい!
Pythonでは、数値や文字列などを変数に代入することもできます。事前に特別な準備をしないで、変数に数値や文字列を代入していることに注目してください。Pythonでは、数値や文字列などを代入をするだけで変数を自動的に用意してくれます。また、同じ変数に違った種類のデータを代入することができます。このような特徴からPythonは動的言語と呼ばれています。
組み込み型
プログラムで扱うデータにはさまざまな種類があります。数を扱うための数値、テキストを扱うための文字列など、データの種類を型と呼びます。Pythonには、プログラムでよく利用するデータを扱うための型が何種類か用意されています。あらかじめ組み込まれていてすぐに利用できる、というような意味で組み込み(ビルトイン)型と呼ばれています。
Pythonには以下のような組み込み型が用意されています。
数値型
数を扱うための型です。数の精度に合わせて整数型、浮動小数点型に分かれています。四則演算を使って計算を行うことができます。
Python 3で1/2を計算すると,結果は0.5になります。ところが,Python 2までは,1/2を計算すると0(ゼロ)という結果が返ってきました。Python 2は計算結果の数値の精度を維持しようとし,整数と整数の割り算の結果が整数になっていたのです。Python 3では必要に応じて小数が返るように機能が変更されました。
数値型の例:
:::python
123,3.14
文字列型
テキストデータを扱うための型です。文字列を定義するにはテキストを引用符で囲みます。引用符1つか、または3つで文字列を囲んで文字列型のデータを定義します。ダブルクオーテーション(")、シングルクオーテーション(')どちらも利用できます。Python 3の文字列型は,アルファベットや数字の他,漢字やひらがなのようなマルチバイト文字列も扱えます。
文字列型の例:
:::python
"Python","""Long string""",'日本語'
また、文字列はシーケンス型と呼ばれるデータ型の一種です。インデックスを指定して文字列の要素にアクセスしたり、スライスと呼ばれる機能を使って文字列の一部を取り出すことができます。
Pythonでは,漢字やひらがなのようなマルチバイト文字列をふくめ,文字列はユニコードとして扱われます。エンコード変換の機能を使うと,文字列をシフトJISやEUC-JPのような他のエンコードに変換できます。
Python 2までは,アルファベットや数字のようなASCII文字列と漢字のようなマルチバイト文字列の扱いが別でした。前者は文字列型,後者はユニコード文字列として扱う必要があったのです。Python 3になって,文字列の型が統一され,Python 2のユニコード文字列は廃止されました。
bytes型
Python 3にはもう一つ,bytes型(バイト型)という文字列型があります。この型は純粋なバイト列を扱うための型です。
Python 3の文字列型はユニコードベースです。そのため,ファイルから文字列を読み込み文字列型に変換するためには,エンコードの情報を与えてあげる必要があります。ファイルやネットから読み込んだ,エンコードの確定していないデータをそのまま扱うためには,このbytes型を使います。
Python 3の文字列型では,マルチバイト文字列の境界をただしく判定できるので,たとえば「123」も「あいう」も3文字となります。bytes型は文字列の境界については関知しません。そのため,「123」はASCIIのバイト数として3文字となりますが,「あいう」のようなマルチバイト文字列は,例えばユニコード相当の文字列であれば6文字となります(文字数(バイト数)は,エンコードに依存して変化することに注意して下さい)。
bytes型の例:
:::python
b"pure 8bit bytes string"
リスト型
複数のデータを順番に並べて管理するために利用する型がリストです。文字列と同じシーケンス型に分類されます。文字列は文字を専門に扱いますが、リストには数値や文字列、そしてリスト自身を含めてあらゆるデータを登録できます。
リストの例:
:::python
[100, 200, "abc", 'あいうえお']
順番に並べたデータの一要素は,インデックスを使って取り出すことができます。インデックスは0から数え始めます。「a_list[2]」のようにすると、a_listというリストの3番目の要素を取り出せます。「a_list[3]=5」のように要素を指定して代入を行うことで,要素の入れ替えができます。リストに対して足し算をして要素を追加したり、メソッドを使って要素の削除ができるのもリストの特徴です。
リストの面白い機能としてスライスがあります。指定した区間にある複数のデータをリストとして取り出す機能です。スライスでは、要素を取り出す範囲をコロン(:)を使って指定します。10個の要素があるa_listというリストに対して「a_list[2:5]」としてスライスを使うと、3番目から5番目の要素を取り出せます。スライスに対して代入を行うと、複数の要素を同時に置き換えることもできます。
辞書(ディクショナリ)型
リストと同様に複数の要素を管理するために利用する型です。簡易なデータベースのように利用できます。リストと違うのは、要素をキーで管理することです。リストや文字列のようなシーケンス型に対して、辞書のようなデータ型をPythonではマップ型と分類しています。
辞書を定義するときには、キーと対応する値をコロン(:)で区切って定義します。
辞書の例:
:::python
{'one':1, 'two':2}
リストと違い、辞書には順番という考え方がありません。要素を取り出す時には「a_dict['one']」のようにキーを使います。「a_dict['three']=3」のように辞書に代入をするとき、キーがなければ新たなキーが登録されます。キーがある場合には要素だけを入れ替えます。
要素を参照するとき、存在しないキーを指定するとエラー(Key Error)になります。キーをスマートに扱うことが、辞書を便利に使いこなすための鍵となります。
タプル型
リストと同様に、複数のデータを順番に管理するために利用するデータ型です。リストと違う点は、要素の入れ替えや削除、追加ができないという点です。変更する必要のないデータ、変更されては困るデータを扱うときに活用します。
タプル型の例:
:::python
(100, 200, "cde")
その他の組み込み型
他にも、Pythonはいくつかの組み込み型を持っています。コンピュータ上のファイルを扱うためのファイル型はその1つです。
集合型とも呼ばれるset型も組み込み型の一種です。set型はリストのようなシーケンス型のデータ型です。リストとの違いは、要素が重複しないように保たれるという点です。そのため、整数の1という要素を持っているset型のデータにさらに1を追加しようとしても、新しい要素として追加されません。Python 3からは,「{1, 2, 3}」のように波括弧を使ってリスト型をリテラルとして表記できるようになっています。
なお、Pythonでは文字列のパターン検索を行う正規表現は組み込みの機能として用意されていません。Pythonで正規表現を使うには、モジュール(re)をインポートする必要があります。
フロー制御
プログラムには、実行したい処理を実行したい順番に記述していきます。処理の流れのことをフローと呼びます。条件によって処理を分けたり、繰り返しを行うことをフロー制御と呼びます。
フロー制御では、対象となるコードの「ここからここまで」という範囲を指示する必要があります。プログラムの中で、どこからどこまでを条件によって実行したいのか。またはどの部分が関数に相当するのかを、プログラミング言語に分かるように指示する必要があるわけです。このような部分はブロックと呼ばれています。
Pythonでは、ブロックを表現するのにインデント(字下げ)を利用します。ブロック表現にインデントを使うということが、Pythonの大きな特徴の1つとなっています。ブロックの左側が揃うため、見た目でブロックを判断しやすくなります。このため、自然と読みやすいプログラムを書けるわけです。
図05 Pythonではブロックをインデントする
条件分岐(if文)
Pythonで条件分岐を行うにはif文を使います。if文には、括弧などを添え ず条件式を記述します。条件が真(True)のときに実行したいプログラムはインデントします。
if文の例:
:::python
if year > 2000 and year <= 2100:
print("21st century")
elif year > 2100 and year <= 2200:
print("22nd century")
else:
print("20th century(maybe)")
上記の例では数値の入った変数を使って条件分岐をしています。andやorと組み合わせると、論理式を使った条件分岐ができます。
elifの条件は、最初の条件が成り立たなかったときに評価されます。Pythonにはswitch文がありません。代わりにifとelifを組み合わせるとよいでしょう。elseのブロックは、どの条件も成り立たなかったときに実行します。
if文に添える条件式には、==や<のように真偽値を返す比較演算子を使います。Pythonでは、空の文字列や空のリスト、空の辞書などが偽(False)として扱われます。要素のある文字列やリスト、辞書は真として扱われます。この性質を使うと、オブジェクトが空かどうかを手早く調べることができます。
シーケンスを使った繰り返し(for文)
Pythonで繰り返しをしたいときに利用するのがfor文です。Pythonのfor文 では、リストのようなシーケンスをinの後に添えて記述します。シーケンスの内容を1つずつ取り出し、inの前にある繰り返し変数に代入しながらブロックの内部を処理していきます。この例では、組み込み関数range()を使って0から9までのリストを生成して、ループブロック内のコードを実行します。
Pythonではブロックごとに名前空間が区切られません。そのため、for文で定義した繰り返し変数や、ループブロックで定義した変数はfor文の後でも利用できます。
for文の例:
:::python
for cnt in range(10): # 0から9までの数を表示する
print(cnt)
条件を使った繰り返し(while文)
条件が成り立つときにだけループを実行したい場合にwhile文を使います。
while文には真偽値を返す式を添え、式が真の間だけ、ブロック内のコードを実行します。
while文の例:
:::python
while cnt < 10:
print(cnt)
cnt+=1
関数定義と呼び出し
関数は、繰り返し使う処理をあらかじめ定義しておくために利用します。defに続けて関数名と括弧を記述します。関数として実行するプログラムはインデントして記述します。
関数定義の例:
:::python
def a_function(arg1, arg2):
"""2つの数値をかけ算して返す"""
return arg1 * arg2
def文のすぐ下にある文字列はドキュメンテーション文字列と呼ばれています。Pythonには、関数の説明をドキュメンテーション文字列に書いておく、という決め事があるのです。
Pythonでは、関数は呼び出し可能オブジェクトとも呼ばれています。Pythonで関数を定義すると、関数として呼び出すことができる「変数のようなもの(=オブジェクト)」が作られる、と思ってください。
事前に定義されていない変数を使おうとするとエラーになります。関数を利用するプログラムの前で、関数定義をしておく必要があります。Pythonでは、関数は変数と同様に扱われるわけです。ですので、別の変数に関数を代入することもできます。
引数の定義
関数にデータを渡して処理をしたいときには、関数に引数を定義しておきます。先ほどの例では「arg1」と「arg2」が引数に当たります。「arg1=10」のように、引数名に代入をするような記述をすると、引数のデフォルト値を指定できます。デフォルト値が設定された引数は、呼び出し時に省略することができます。
*paramのように、アスタリスク(*)を使った引数は特殊な意味を持ちます。定義されている数以上の引数を渡して関数を呼び出すと、あふれた引数がリストとしてparam引数に入って呼び出されます。引数の数を指定しない関数を作りたいときに利用すると便利です。
**argsのようにアスタリスクを2つ付けた引数を定義することもできます。このような引数を定義すると、関数は不定個のキーワード引数を受け取れるようになります。argsには辞書が渡されます。関数内では、キーワード引数の引数名のキーに、値が登録された状態で利用できます。
関数の戻り値とアンパック代入
関数の外部に処理結果を渡したいときにはreturn文を使います。Pythonのreturn文には括弧を添える必要はありません。関数の外に受け渡したいデータをそのまま記述します。先ほどの例ではarg1とarg2をかけ算した値を戻り値としています。
Pythonでは、複数のデータを一度に戻り値として返すことができます。「return a, b, c」のように複数の値をカンマで区切るか、タプルを返します。関数を呼び出す側では「a, b, c=somefunc()」のように複数の値を受け取ることができます。タプルを自動的に展開して代入することから、これをアンパック代入と呼んでいます。
関数と名前空間
Pythonでは代入を行うことで変数を定義します。変数は、どこで定義されたかによって利用範囲が制限されます。Pythonの関数内では、特別な名前空間(Name Space)が作られます。関数内で定義された変数は、この名前空間の中でだけ利用できます。ですので、関数で定義した変数を外部で利用することはできません。引数も、関数内で定義された変数と同じような扱いを受けます。
関数の処理結果を外部で利用したいときには、戻り値として関数の外部に値を受け渡します。
関数の呼び出し
事前に定義された関数は、次のようにして呼び出せます。
:::python
a_function(1, 2)
関数が戻り値を返すようになっている場合は、戻り値を変数に代入したり、計算など別の処理に利用できます。戻り値がない場合はNoneという特別な値が返されます。
引数の指定方法には2つの方法があります。上記のように直接値を指定する方法が1つ。そして次のように変数名をキーワード指定する方法です。
:::python
a_function(arg1=1, arg2=2)
キーワード指定をすると、定義順に関係なく、引数を指定できます。
モジュールの活用
Pythonには標準ライブラリと呼ばれるモジュール集が搭載されています。標準ライブラリを使うことでPythonの機能を大幅に拡張することができます。テキスト処理やネットワーク処理、数値計算など、便利で強力な機能を備えたライブラリがたくさん用意されています。Webアプリケーションなどを作るときに利用する処理の多くが、標準ライブラリにすでに入っています。
Pythonを使えば、基本的な処理を実行する関数をゼロから作る必要はありません。また、インターネットを探し回ってライブラリをインストールする必要もないのです。Pythonをインストールするだけでこのような機能が利用できるため、Pythonはバッテリ付属(Battery included)言語と呼ばれることもあります。
モジュールのインポート
モジュールを利用し、Pythonの機能を拡張するにはimport文を使ってモジュールをインポートします。インポートには2つの種類があります。モジュール名を指定してモジュールをインポートする方法と、from文を使ってモジュールの一部をインポートする方法です。
モジュールインポートの例:
:::python
import re
from urllib.request import urlopen
モジュールのインポートは、プログラムのほとんどすべての場所で実行できます。関数やif文などのブロックでもモジュールのインポートを実行できますが,特別な理由が無い限り,プログラムの先頭でまとめてモジュールをインポートするようにしましょう。
インポートしたモジュールは、変数や関数と同じようにオブジェクトとして扱われます。変数や関数と同様に、モジュールを利用する前にインポートしておく必要があります。また、関数内部のように、特別な名前空間を持っている場所でインポートしたモジュールは、その名前空間の内部でしか利用できません。
モジュールの作成
Pythonのようなプログラミング言語を使うとき、プログラムを事前にファイルに書いておくことがあります。プログラムを書いたファイルを指定してPythonを実行することで、何度もプログラムを実行できます。プログラムを書いたファイルをスクリプトファイルと呼ぶことがあります。
Pythonではスクリプトファイルがモジュールとして扱われます。モジュールを作って関数などを利用したいときには、スクリプトファイルを作ればよいわけです。スクリプトファイルのファイル名がそのままモジュール名になります。
たとえば、a_module.pyというファイルにsome_func()という関数を定義したとします。外部からは、以下のように利用できます。
:::python
import a_module # モジュールをimportする場合
a_module.some_func()
from a_module import some_func # 関数だけをimportする場合
some_func()
モジュールをインポートすると、Pythonはスクリプトファイルを先頭から読み込んで書かれているプログラムを実行します。スクリプトファイルを読み込む課程で、定義されている関数などをモジュールの「持ち物」として登録します。関数だけでなく、変数などもモジュールの持ち物として登録されます。
インデントの一番浅いところをトップレベルのブロックと呼びます。トップレベルのブロックに記述されているプログラムは、モジュールをインポートする課程で必ず実行されます。モジュールの初期化用のコードは、トップレベルに記述するとよいでしょう。