この記事は2017/12/23に岡山県立大学であった合同勉強会 in 大都会岡山 -2017 Winter-で発表した内容の紹介とその補足です。
合同勉強会 in 大都会岡山 -2017 Winter- とは
こちらの合同勉強会はわたしも初めて参加したので詳しくないのですが、岡山近辺で活動しているコミュニティの方々が一堂に会して行なっている勉強会です。 テーマのようなものは特になく、自分の好きな内容で発表できました。
ちなみに当日のスケジュールはconnpassに載ってます。 下記のように発表者が多く、広く浅く、中にはとても深い内容のセッションもあり、いろんな分野の話が聞けてとても面白かったです。
- セッション(20分) - 岡山県民枠 7/7人
- セッション(20分) - 県外ゲスト枠 7/7人
- LT(5分) 6/6人
わたしがこの合同勉強会の存在に気づいた時にはまだ枠が余ってたので、今回は県外ゲスト枠で申し込みました。 今後も機会があればどんどん表に出ていきたいので、面白そうな機会があればぜひ教えてください。
Python再発見 - デコレータとその活用パターン -
今回は「Python再発見 - デコレータとその活用パターン -」と題して発表してきました。
スライド作成には初めてslideshipを利用してみましたが、とてもよかったです。
欲を言えばconnpassの資料ページみたいに自分のページにも埋め込めると嬉しいと思いました。
Python利用者の動向
セッションの冒頭でPythonとデコレータをどれくらい使っているのか質問をしてみたところ、結果は下記のような感じでした。
- Pythonを使ったことのある人: 会場の7-8割
- デコレータを使ったことのある人: 会場の1-2割
- デコレータを書いたことのある人: 2-3人
嬉しい誤算はPythonを使ったことのある人の多さ! いろんなバックグラウンドを持つエンジニアが集まる中でめっちゃ手が上がり、Python人気を実感しました。
逆にデコレータに関しては思いの外、(割合として)利用者がいなかったですね。 Web系の方なら(Webフレームワークで提供されてることが多いので)結構利用者いるのかなと思っていたのですが、 今はデータ分析や機械学習から入った方が多く触れる機会が少ないのかなと感じました。
スライドの補足
デコレータの説明はスライドに書いてますので、そちらをご覧ください。 ここからはスライドの補足として、スライドで紹介している活用例のソースコードのリンクと簡単な説明を記載しておきます。
bottleのルーティング
bottle.routeのコードはこちらになります。
routeデコレータの実体はBottleクラスのインスタンスメソッドとして定義
されています。
アプリ起動時にデコレート対象の保持するRouteインスタンスを作成し、Bottleのインスタンス変数self.routeに格納していますね。
Djangoのアクセス制限
login_requiredのコードはこちらになります。
こちらのデコレータの実体は別の関数として定義
していますね。
チェックロジックを外部から渡すことでlogin_requiredとpermission_requiredという2つのデコレータを1つの関数で実装しています。
メモ化
functools.lru_cacheのコードはこちらになります。
デコレータが動作するタイミングはそのデコレータを利用した関数が読み込まれるタイミングになっていて、変数cacheなどはこのタイミングで初期化されます。
そして、関数wrapperはそれらの変数への参照を保持したクロージャになっている
ため、関数の実行時に値を保持したり保持しておいた値を参照することができています。
コンテキストの上書き
override_settingsのコードはこちらになります。
このデコレータはコレまでのものとは違い、(TestContextDecorator)クラスとして定義
されています。
Pythonでは、__call__
メソッドを持つオブジェクトは呼び出し可能なオブジェクトと呼ばれ、関数やメソッドのように()
をつけて呼び出すことができます。
状態を管理する必要があるような複雑なデコレータでは、このようにクラスとして実装されることもあります。
また、このTestContextDecoratorクラスは__enter__
メソッド、__exit__
メソッドを持つコンテキストマネージャでもあります。
このため、設定情報を上書きする際にwith
文を利用することで、テスト完了時に必ずdisable()メソッドが呼ばれることが保証されています。
セッションで紹介した活用パターンは以上です。
大事なこと
そういえばセッションで1つ大事なことを言い忘れていたのですが、Pythonのデコレータはあくまでデコレータであって、アノテーションとは呼びません
。
Javaのアノテーションと同じ「@hoge」という記法を使ってはいますが、呼び間違えないようにしましょうw
まとめ
セッション中でも何度か出てきますが、デコレータは下記のように単なるシンタックスシュガーに過ぎません。
# デコレータの利用
@deco
def func():
...
これは下記と等価
func = deco(func)
ただし、概念が非常にシンプルなものであっても、Pythonのデコレータは使い方次第でとてもパワフルな機能となります。 スライドやこの記事にあるように非常に多くの活用シーンがあり、様々な方法で作ることができます。 ぜひ活用していきましょう。