Book Review programming プログラミング
Book Review O'Reilly Japan「退屈なことはPythonにやらせよう」
「退屈なことはPythonにやらせよう」(原著: Automate the Boring Stuff with Python)。
GW前半を使ってやっと読みきれた最近話題のPythonのhowto本。全部で600ページくらいあった。
転職してからは、業務としてPythonを書く割合が多くなったということと、少し前にオライリー本のランキングで首位だったこともあって読んでみた。
読む前は、
「日頃の業務で自動化できることはどんどんPythonで書いていこう!」
って感じのツールがたくさん書いてある本かと思っていたけど、読んでみたらPythonの変数の型の説明から入って、ファイル入出力や正規表現、デバッグの仕方から最後は画像解析とかGUIの自動化まで広くカバーしていて結構参考になるところがあった。
Pythonという言語を知らない人には、Pythonがどんな言語でどんなことができるツールをどんな感じで作ることができるのかを体系的に学んでいくことができるのでおススメ。
(ただ、Pythonの強みである仮説検証とか機械学習のことについてはノータッチなので注意)
ということで、本のレビューはここまでにして個人的に参考になったところを備忘録として少しだけ列挙していきたい。GW明けにこの辺を意識してこれまで書いてきたコードをrefactoringしていきたい感じ。
値の初期化にはset.defaultを使う
これはdictの初期化に使えるらしく、これまでkeyが存在しない場合は以下のように書いていたif節がキレイに書き換えられるとのこと。
# ここのifがtest_dict.setdefault(k, 0)だけで済むように
test_dict[k] = test_dict[k] + index if k in test_dict else 0
いつも、「もっと良い書き方ないかな〜」と思いながら書いていたこともあって結構嬉しい学び。
正規表現にはraw文字列を渡す
この辺から正規表現の話が続いていくけどご勘弁。
まず、正規表現はraw文字で定義するのが良いらしい。というのも、raw文字で指定するとエスケープする必要がなく可読性が上がるということから。
短いと恩恵がわかりにくいかもしれないけど、超基本的な携帯電話のマッチパターンの正規表現を
re.compile('\\d\\d\\d-\\d\\d\\d\\d-\\d\\d\\d\\d')
こう書いていたものが、
re.compile(r'\d\d\d-\d\d\d\d-\d\d\d\d')
と書ける。エスケープするしないで結構ハマったことがあったので、raw文字で統一できるならありがたい。
正規表現のグルーピングはgroups()でtupleが取れる
これは正規表現でマッチした後の後方参照の話。group()で添字ありでしか取れないと思ってたけどgroups()を使うとマッチしたところが取れるらしい。
>>> target_str = '123-4567-8910'
>>> phone_reg = re.compile(r'(\d\d\d)-(\d\d\d\d-\d\d\d\d)')
>>> m = phone_reg.search(target_str)
>>> m
<_sre.SRE_Match object; span=(0, 13), match='123-4567-8910'>
>>> m.groups()
('123', '4567-8910')
>>> m.group(0)
'123-4567-8910'
>>> m.group(1)
'123'
>>> m.group(2)
'4567-8910'
>>> area_code, main_number = m.groups()
>>> area_code
'123'
>>> main_number
'4567-8910'
正規表現patternはVERBOSEオプションで綺麗に書ける
正規表現を改行で区切ってキレイに書くオプションがあったらしい。これも可読性高めるために使えそう。
>>> phone_regex = re.compile(r'''(
... (\d{3}|\(\d{3}\))?
... (\s|-|\.)?
... )''', re.VERBOSE)
>>> phone_regex
re.compile('(\n(\\d{3}|\\(\\d{3}\\))?\n(\\s|-|\\.)?\n)', re.VERBOSE)
pathの扱いはos.pathライブラリが結構充実している
自前でsplit('\')[-1]とかしてファイル名抜いていた時期もありました。。
os.path.join()とかos.path.split()とかがめちゃ便利なので活用していきたい。
プログラマのミスはassert機能で検知しやすく
事前にミスを防ぐにはコメントとtest書くくらいしかないと思っていたけど、assert機能を使うことで、「この場所にはこの値が来ないはず」みたいな状況を検知できるらしい。
結構なるほど感があったので引用。
アサートはユーザの失敗ではなくプログラマーの失敗のための対策です。ファイルが見つからないとか、ユーザが間違ったデータを入力したといった回復可能なエラーは、assert文で検出するのではなく、例外を起こしましょう。
ちなみに組み込み関数によってアサート機能の有無は指定することができるということで使い勝手も良さそう。
printデバッグよりlogging機能
pythonのloggingモジュールの話。これまで、簡単なスクリプトのデバッグはprintデバッグとかpython debugger(pdb)とか使っていたけどこのlogging機能が結構便利そうだった。
これまでprint文を書いたり消したりコメントアウトしたりとしていた面倒が一気に解消されそう。
こちらも前述のアサート機能と似ていて組み込み関数をいじることでログの表示、非表示を指定することができるそう。
ということで、簡単ではあるが、自分のためになった部分を書いてみた。
とりあえずは、チェックシートか何かを作ってこの辺を意識しながらコードを書いていくつもりだが、ゆくゆくは自分のコードスタイルとして取り込んでいきたい。