関数と変数の定義
関数は、def文で定義します。括弧の中には引数を記述します。Pythonの変数には任意の型が入れられるので、引数にも型の指定はありません。戻り値は、returnで指定します。戻り値を省略すると、Noneと言うnull値が返ります。
def 関数名(引数名): 処理内容 return 戻り値
変数は、変数名=値
で宣言します。PerlのmyやJavaScriptのvarのような予約語はなく、最初に代入文が現れたところが宣言となります。ただし、宣言となるのは代入文だけです。未宣言の変数を使うと、エラーとなります。
また、変数には型がなく、任意の型のデータを保存できますが、演算における型は厳密であり、異なる型での演算はできません。
a = 3 # 宣言 a = a + 1 # 4を代入 a = "変数です" # 文字列を代入 a = a + 2 # 文字列へ数値は足せないので TypeError a = b # bは宣言されてないので NameError
この変数定義一つをとってみても、Pythonがいかに単純で秩序のある規則で設計されているかが見て取れると思います。予約語の少ないシンプルな言語仕様が、初学者の学習コストを落としているのです。
イテレータの多用
Pythonでは、イテレータが言語仕様として組み込まれており、至る所に登場してきます。それをよく表しているのがfor文で、JavaやC言語とは異なり、Pythonのfor文ではイテレータを繰り返すことしかできません。ちょうどPerlのforeachにあたります。
# 0から9を表示 for i in range(10): print i
range(n)は、0からn-1までのn個の連続する自然数のリストを作成します。このようにして、JavaやC言語のようなループカウンタによるfor文を実現します。イテレータに関してはPythonにおいてかなり面白い部分なので、後で詳しく説明します。
文字列における%演算子
地味だけど便利な機能がこの%演算子です。平たく言うとsprintfで、文字列 % タプルと言う使い方をします。タプルとは変更不可能なリストで、括弧()で定義します。
また、辞書型で名前付きのフォーマット文字列へ埋め込むこともできます。その場合、%(value)02dのように、フォーマット文字列と%の値にキー名をいれます。辞書型は中括弧{}で定義します。
# sprintf "count of %s: %d" % ("X", 10) # 辞書で名前付きのパラメータを埋める '%(key)s = %(value)03d' % {"key": "X", "value": 10}
豊富な標準ライブラリ
Pythonには、初めから多くの有用なモジュールが含まれています。ライブラリを利用するには、import文で対象となるモジュールをロードします。サンプルスクリプトでimportしているfileinputモジュールは、shellコマンドでよくある、「引数をファイルとして処理するか、引数がなければ標準入力から読み込む」という処理をやってくれる便利なモジュールです。input()
関数を呼ぶと、1行ずつファイルや標準入力の内容を返してくれるイテレータが戻ってくるので、これをループさせて処理します。
他にも、正規表現、シリアライズ、ロギング、Unit Test、スレッド、CGI、XML-RPC、e-mail、Tcl/Tkなど、多くの機能が標準ライブラリとして初めから利用できる状態で提供されています。
シンプルなモジュール化機構
Pythonのモジュール機構は非常に簡単、かつ、柔軟であり、全ての実行可能スクリプトをモジュールとしてロードすることができます。逆に言えば、実行可能なファイルとimport可能なモジュールの区別はありません。
これを実現するのに利用されるのが、module
型の特殊属性である__name__
です。__name__
にはモジュール名(ファイル名)が入りますが、そのファイルがエントリポイントとなっている場合には'__main__'
という値が入ります。これを利用して、
if __name__ == '__main__': # メインルーチン # ここから先は、スクリプトとして実行されたときだけ走る
と、if
文を利用してメインルーチンを書くと非常に便利です。これはJavaで、staticなmain()
メソッドに主処理を書くのと同じようなものと見なせます。単体では実行されないような汎用的なモジュールであれば、ここにテストルーチンやデモルーチンを置いておくと、モジュールの動きをちょっと試したいときなどに役立ちます。
そして、上記のようなif
ブロックにメインルーチンを閉じ込めるというルールを守っておけば、逆もまた然りです。つまり、この「mycount.py」のように実行されることを前提として作られたスクリプトでも、部品として他のスクリプトから読み込むことができるということです。以下に、「mycount.py」内のwordcount()
関数を再利用するスクリプトの例を挙げます。
#!/usr/bin/env python2.5 # coding: utf-8 """mycount.py の再利用の例 """ # mycount モジュール(スクリプト) をインポート import mycount def count_file(file_path): """与えられたファイル名により、その中に含まれる文字数をカウントする """ # インポートした mycount.py の関数を利用する chr_cnt, line_cnt = mycount.wordcount( file(file_path) ) return (chr_cnt, line_cnt) if __name__ == '__main__': # テスト用のメインルーチン print "%d characters, %d lines" % count_file("test.txt")
さらに、この「countfile.py」も先ほど書いたルールを守っているので、他のスクリプトからimport可能です。このように、スクリプトを部品として再利用するといったことが、自然に実践できるようになっています。
なお、Pythonのモジュール機構で、一つだけ気をつけておくべき点があります。Pythonのimport文はJavaと同様にドット(.)区切りでディレクトリ階層を表しますが、モジュールとして認識されるディレクトリには必ず「__init__.py」というファイルが必要です。
例えば、a.b.cというモジュールを作りたければ、以下のファイルが必要です。これは、意図せぬフォルダにあるファイルを、モジュールとして勝手にLoadされないために設けられている仕様です。
a/__init__.py a/b/__init__.py a/b/c.py
これはJavaやPerlとルールが異なりますので、気をつけましょう。
日本語対応
日本語もきちんと考慮されており、使うことができます。先頭行か、先頭から二番目に以下のような宣言を書きます。この表記はイコール(=)かコロン(:)で区切られていれば、かなり柔軟に評価されるのでどんな書き方もできます。推奨されているのは、以下のようにEmacsが認識できる形式です。
#!/usr/local/bin/python # -*- coding: sjis -*- # ↑もちろん、このファイルで利用している文字コードを指定して下さい
この宣言があれば、字句解析やリテラルの評価の際に、適切にUnicodeへの変換処理が走ります。ただし、文字列リテラルに関しては、何もしなければただのバイト列になってしまいます。以下のように、クォートの前にuをつける必要があります。
unicode_str = u"日本語でもオッケーです"
Unicode文字列とバイト列の変換には、encodeとdecodeというメソッドを使います。
# Unicode文字列へ デコードする unicode_str = "日本語でもオッケーです".decode('sjis') # バイト列へ エンコードする euc_byte_str = unicode_str.encode('euc-jp')
日本人にとって、プログラミング言語で日本語をどう扱うかというのは非常に重要な問題ですが、Pythonのように言語機能に他言語サポートがきっちりとしてあると、安心して利用することができます。
動作可能な疑似コード
以上で、「mycount.py」の解説は終わりです。ここまで書いてあることを読めば、「mycount.py」のコードは苦もなく自然と読めるようになるのではないでしょうか?
Pythonの予約語は、30前後しか存在していません。これは、他の言語と比べても少ない数です。Pythonは、予約語を少なくし、シンプルな言語仕様を保つことで、初学者にも理解しやすい「動かせる疑似コード」を実現しようとしています。