Pythonのようなスクリプト言語の特徴の一つとして,データをソースコードに直接埋め込みやすい,というものがあると思います。実際,Pythonのコードを見ると文字列,リストや辞書といった高機能で使い回しのしやすいデータ型が,リテラルとしてソースコードに埋め込んであるのをよく目にします。時には変数に代入されたり,時には関数やメソッドの引数部分に埋め込まれたり。
いちいち離れた場所にあるデータを見に行ったり,オブジェクトを作るための宣言をする必要がなく,処理をしたい場所の間近にデータを埋め込めるので,とても便利なのですが,欠点もあります。無造作にデータ型のリテラルを埋め込んでいると,ソースコードが横に長くなって,見にくくなってしまいます。可読性が低くなるわけですね。可読性の悪いコードを書くことは,Pythonの文化に反します。すべてのソースコードは見やすくあるべきです。Pythonでは80文字くらいでソースコードを改行すべき,という暗黙のルールがあります。横に長くなったソースコードは,適当な位置に改行を入れると見やすくなります。
インデントでブロックを表記する特徴から,Pythonはホワイトスペース(空白)に厳密な言語だと思われがちです。しかし,一面ではこれは間違っています。Pythonは,2,3のルールを守りさえすれば,空白について寛容に対処してくれます。ここでは,改行をうまく活用して,Pythonのコードを見やすく整形するTipsをいくつか紹介します。
長い文字列をきれいに埋め込む
文字列は,ソースコードの横幅が長くなる原因の代表格かもしれません。たとえば,パスワードチェック時に気の利いたメッセージを例外として投げたいとします。....
if 8 > len(password) or len(password) > 24 or re.match(r'(\w+)', password):
raise ValueError(" '%s'はパスワードとしては適切ではありません。パスワードは8文字以上24文字以内で、'_'と英数字で構成してください。英字の大文字,小文字は区別されます" % password)
長い文字列をきれいに埋め込むために,トリプルクオートが使えます。
....
if 8 > len(password) or len(password) > 24 or re.match(r'(\w+)', password):
raise ValueError(""" '%s'はパスワードとしては適切ではありません。
パスワードは8文字以上24文字以内で、'_'と英数字で構成してください。
英字の大文字,小文字は区別されます""" % password)
インデントを維持したい場合は,カッコを使います。カッコに続けて,複数の文字列を並べます。このとき,文字列の間にコンマは使わないようにします。カッコ内の文字列が自動的に連結されて,一つの文字列になります。
....
if 8 > len(password) or len(password) > 24 or re.match(r'(\w+)', password):
raise ValueError( (" '%s'はパスワードとしては適切ではありません。"
"パスワードは8文字以上24文字以内で、'_'と英数字で構成してください。"
"英字の大文字,小文字は区別されます") % password)
リスト,タプル,辞書などのリテラルをスマートに埋め込む
リスト,辞書,タプルなどの組み込み型もコードを汚くする原因になりがちです。多くの要素を含むデータ型のリテラルを記述するときが要注意。for name in ('name', 'furigana', 'postal', 'address1', 'address2', 'company', 'organization', 'comment'):
print """<input type="text" name="%s">""" % name
Pythonはカッコの中の改行や空白文字列にはとても寛容です。カッコの中で改行したり,自由に空白文字列を使うことが出来ます。
for name in ('name', 'furigana', 'postal', 'address1',
'address2', 'company', 'organization', 'comment'):
print """<input type="text" name="%s">""" % name
'age':4,
'birthplace':'東京',
'introduction':("""吾輩は猫である。名前はまだ無い。"""
"""どこで生れたかとんと見当がつかぬ。"""
"""何でも薄暗いじめじめした所で"""
"""ニャーニャー泣いていた事だけは記憶している。"""
"""吾輩はここで始めて人間というものを見た。""") }
関数やメソッドの呼び出し,定義
関数呼び出しにデータ型のリテラルを埋め込むとソースコードが横に長くなりがちです。r = urllib2.urlopen('http://foo.bar.com/post_something', urllib.urlencode({'name1':'value1', 'name2':'value2'}))
カンのいい人なら,関数呼び出しもカッコで囲まれていることに気づくはずです。Pythonの「カッコの中では寛容」という特徴を使うと,こんな風に書けます。
r = urllib2.urlopen('http://foo.bar.com/post_something',
urllib.urlencode({'name1':'value1',
'name2':'value2'}))
メソッドや関数の定義も同様で,改行や空白を入れることが出来ます。
arg3 = "some default string",
arg4 = ('value1', 'value2', 'value3'))
# do something
長〜いimport文
import文もコードを横長にすることがありますね。これは実際に私が書いたPloneのコードです。ATCTFileContent, updateActions)
インターネット上で公開されているPythonのソースコードには,これらのテクニックがよく使われています。テクニックを知ることで,自分のコードをきれいに書けるようになるのはもちろんですが,他の人のソースコードも読みやすくなるはずです。