Python:ざっくりと仕様をつかむ

突然のPython

 前回GLSLやってたのに、今回は唐突にPythonです。
 WebのカテゴリにPython入れちゃうのもどうかなと思ったんですが、鳶嶋工房(うちのサイト)だとここが一番妥当な気がするので。

 GLSLと同じく、こねくり屋で勉強会やってたんで、それをきっかけに、ひとつやってみるかと。
 特に目的もないんですが、Pythonって言語、人気じゃないですか。
 そんな軽い気持ちで手を出しました。

基礎的な情報

 総本山はpython.org
 日本語はpython.jp
 日本語のドキュメントはdocs.python.jp
 ついでにPython - Wikipedia

 Webの情報だけでも十分学習できそう。
 流石は人気言語。充実してます。

 Python文法詳解って書籍を入手して、そちらを読んでみた。
 本はWebに比べて情報が(大抵は)整理されているので、先に読めるならなんか一冊読んでからWebの情報読んだ方が、何かとスムース。
 基本だけではあるけど、きっちりまとまってる感じの本でした。
 買うべきかと言われると、上記のWebリファレンスの引き写しっぽい部分も多いんで、買ってもいいんじゃない、って程度ですが。
 あれってどう書くんだったっけなー、ってときにペラペラめくる感じの本なので、そういうの置いとかないと不安な人にはいいかもね。
 私は、そういう本がないとWebだけでは若干不安なタイプ。

 このPython文法詳解とは別にオライリーさんから入門書も出てますし、チュートリアルもあります。
 人気言語は本が沢山あっていいね。

Pythonを大づかみに

 ところで、Pythonは蛇から命名されたのではなく、コメディ番組モンティパイソンから名付けられたそうで、Pythonのサンプルコードでは、モンティパイソン由来のspam,hamなどが多用されます。
 つーても、マスコット的に 蛇はよく使われてるみたいです。

 言語仕様はシンプルなままにして、機能は極力モジュールをimportして提供する。
 書き方を選べるのではなく「できうれば一つの良い方法を」提供する。
 というのがPythonのポリシーらしい。

 C言語的スタンダードスタイルを踏襲しつつ「ブロックは:で始まりインデントで範囲で表す」「文末は改行で表す」あたりが大きく異なるところ。
 インデントは最初のインデントと同じものが続いていれば、ブロック内と判断されるようだ。
 Tabでインデントしたら、以後もブロックは全部Tabで統一すること。
 ちなみに、Pythonの推奨インデントは(半角)スペース4個。
 インデントは宗教論争が激しすぎて強制できなかったのか、表示環境の差が大きいので、あえて自由度をつけたのか。

 変数の型も関数も区別なく、なんでもオブジェクト。
 ざっくりした印象では「整理されたPerl」という感じ、そういう意味ではRubyと近い。
 現在はUnicodeを文字コードの基本としているので、日本語を含むマルチバイトコードの処理も、わりと安心して行えるみたい。

 予約語は and, as, assert, break, class, continue, def, del, elif, else, except, exec, finally, for, from, future, global, if, import, in, is, lambda, nonlocal, not, or, pass, print, raise, return, try, while, with, yield というところ。
 これだけで、大まかな言語仕様が想像出来る人も多いかもしんないので、並べておく。
 しかし、そんな人はこのページ読まんだろう…

 論理演算子はand or not、論理値(真偽値)は整数値(int)の派生として存在し、True = 1,False = 0で定義されている。TrueとFalseの頭は大文字なので注意。
 &と|はビットの論理演算子なので、なんとなくバグが出ずに通ったりするけど、別の演算子。

 コメントは#。
 コメントが#だと、俄然UNIXっぽくなるけど、Pythonの出自はUNIXではなくAmoebaというOS(Amoeba (オペレーティングシステム) - Wikipedia)
 …Amoebaってはじめて知った。オランダ生まれなのね。Pythonもオランダ。
 オランダってモンティパイソン人気あんの?
 あと、Pythonは1991年生まれ。もうほとんど枯れてると見ていいでしょう。安心です。
 しかし意外に1987年生まれのPerlと登場時期が離れてないですね。

関数

 関数の定義はfunctionじゃなくてdef。たぶんfunctionは長すぎるという判断だと思う。
 ちゃんとしたコードエディタ使って、関数のスニペット呼出せよ、で済む話ではあるが、最初から短いというのも解決方法の一つではあるので、悪くないと思う。
 変数は、いきなり代入できるんだから、関数も特にdefとか書かずにいきなり定義できるようにしてもよかったんじゃなかろうか、と若干思う。

引数の指定

 引数は位置指定が一般的みたいだけど、仮引数をラベルとするキーワード形式での引数の書き方もできる。
 def x( arg ):、で定義した関数は、x(4)で呼び出せるし、x( arg = 4 )でもいい。
 特に引数が多い場合、キーワード形式の方が位置を気にしなくていいし、ラベルで意味もわかるし、間違いにくくていい。

 あと、関数の定義の際にデフォルト値の設定もできる。
 def x( arg = 4 )みたいな感じ。
 呼び出しの時と定義の時で、同じ書き方でも意味が違うというのが、若干混乱する。
 すぐ慣れると思うけど、学習段階ではちょっと嫌な感じだ。

引数の展開

 引数に指定する(リストのように展開可能な値の)変数の前に*をつけると、引数に展開して渡される。
 **をつけると、辞書がキーワード形式の引数として展開して渡される。
 複数の引数を持つ関数でも、引数を構造体的にまとめて管理できる、というわけだ。

 関数を定義すのところで、仮引数の頭に*をつけると、可変長の引数となる。
 **をつけると、可変長のキーワード形式の引数になる。
 どーもこの仕組みは使わない気がするけど、うまく使ったら便利なのかも。

 *をつけるとC言語のポインタ渡し的な雰囲気になるけど、たぶんその辺意識したんでしょう。

内蔵ヘルプ

 あと、関数の定義直後に直に文字列を置くと、それがそのまま関数のヘルプテキストになる。
 さらに、引数の直後に:を挟んで注釈が書けるし、defの最後に->と書いてその後に戻り値について記述できる。
 これはなかなか面白い仕様だ。
 仕様書(ヘルプ)とコードは極力分離しないほうが管理しやすいんだけど、それを言語仕様の段階でサポートしている。
 ヘルプはhelp関数を使って、help(関数名)てな感じで読み出せる。
 javadocなんかのようにHTMLに変換する手間もなく、賢くすっきり(スマート)だ。
 テキストが返ってくるだけだから、単純すぎるところはあるけどね。

ラムダ関数

 それからdefの他にlambdaという、式のみの関数(オブジェクト)を作る書式もある。
 たぶん、引数に関数を渡すタイプ(ソート関数とか)に対して使うと便利なんだろう。

forループ

 C言語系のforループはfor(初期化;終了条件;カウンタ)、みたいな作りだが、Pythonはfor 変数 in 繰り返し(イテラブル)オブジェクト、という形だ。
 イテラブル(iterable)オブジェクトには、リストみたいなのや、順に値が取り出せる特別なオブジェクトを置く。
 よくあるカウントのforループは、for i in range(1, 5):てな感じで書くと1〜5を変数iに収めながらループしてくれる。なかなか分かりやすい。
 なお、ここでは、rangeがイテラブルオブジェクト。
 イテラブルオブジェクトはユーザ定義もできるので、このイテレータ(Iterator)型のfor inループで、様々なループを表現できる。

for i in range(1, 5):
	pass # これは何もしない、という印。インデントによるブロック必須なので、完全に空にはできない。

 もちろん、for i in [2,3,5]:みたいに、直に配列(リスト)を書くこともできる。

 リスト内包という形で、リストを生成することもできる。
 [式 for 変数名 in イテラブルオブジェクト]、と記述すれば、変数名を基にした式によるリストが生成される。

elseいろいろ

 Pythonのelseは割と独特なので、まとめて書いておく。

 forやwhileループの後にもelseブロックが作れるのがPythonの面白いところ。
 このelseブロックはループが終わったときに1回だけ実行されて、breakでループを抜けたときは実行されない。

 三項演算子の書き方が「条件文?真の値:偽の値」ではなく「真の値 if 条件文 else 偽の値」で、ちょっと自然言語風味。

 ifを連続して書く際のelse ifはelifと書く、…これはelse ifの方が好みだなぁ。

 あと、try文にもelseブロックがつけられて、これは例外が発生しなかったときに実行される。

その他

 その他、いろいろと面白い仕様が目白押しな感じですが、オブジェクト関連あたりは、いまいち理解できてません。
 そんなん作るようになりそうな気がしないもんで、テキトーに流しました。
 モジュール依存度が高いだけに、Pythonでモジュール(クラス)を書くのも簡単なようにできてんな、程度の理解で。

 今日はここまで。