Edited at

Effective Python メモ 項目4 複雑な式の代わりにヘルパー関数を書く

More than 1 year has passed since last update.

Effective Python に関するメモ

項目4:複雑な式の代わりにヘルパー関数を書く

一文の式に複雑な式を書くと可読性が低下するため、ヘルパー関数を書こう

pythonはその気になれば、一文にとてつもない量の構文をかけるが、とても読みにくくなるためヘルパー関数を設けて可読性を高めるべき


URLクエリの内容を取得する例


シンプルな例

# urlクエリから引数を求める


from urllib.parse import parse_qs
my_values = parse_qs('red=5&blue=0&green=',
keep_blank_values=True)
print('red: ', my_values.get('red'))
print('green: ', my_values.get('green'))
print('opacity: ', my_values.get('opacity'))

>>>
red: ['5']
green: ['']
opacity: None

⇒値が無いときはゼロに統一したほうが良い

# or演算子を使って式の前後を比較

red = my_values.get('red', [''])[0] or 0
green = my_values.get('green', [''])[0] or 0
opacity = my_values.get('opacity', [''])[0] or 0
print('red: %r' % red)
print('green %r' % green)
print('opacity %r' % opacity)

>>>
red: '5'
green 0
opacity 0

一応出来たけど、なんか見にくいよね。。。

しかも数字は文字列ではなくて、数式で加工したい場合もある。だからint()でラップしよう!

red = int(my_values.get('red', [''])[0] or 0)

print('red: %r' % red)

>>>
red: 5

かなり見にくい状態。一目で理解できる人はそうそう居ないでしょう。

そもそもそこまで1行に収める必要はない。

if/elseでわかりやすく条件判定しましょう

red = my_values.get('red', [''])

red = int(red[0]) if red[0] else 0
print('red: %r' % red)

>>>
red: 5

少しすっきりしたが、if文の記述が綺麗じゃない

厳密なif文で記述すると

red = my_values.get('red', [''])

if red[0]:
red = int(red[0])
else:
red = 0
print('red: %r' % red)
>>>
red: 5

伝わるけど、また見づらくなった。


もうヘルパー関数を書こう

def get_first_int(values, key, default=0):

found = values.get(key,[''])
if found[0]:
found = int(found[0])
else:
found = default
return found

red = get_first_int(my_values, 'red')
print('red: %r' % red)

>>>
red: 5


まとめ

pythonは便利は記述がたくさんあるけど、使い過ぎると折角の可読性を残ってしまう。

状況に応じてヘルパー関数をたくさん書くべし。