主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python: デコレータ

                
tags: python
 GoogleAppEngine(GAE)を使っていたところ、以下のような@つきのものを見て少し不思議に思っていた。
@login_required
def get(self):
pass


この"@login_required"をリクエストハンドラクラスのgetメソッド宣言の直前につけると、ログイン済みのクライアントのみにをアクセス許可を与えることができた。なんじゃこりゃ。


 デコレータの話へ。"@"はデコレータと言って、ある関数をそのままに、その前後に処理を付け加えられるようだ。たとえば引数とされた文字列を出力する関数を、divタグでくくった出力をするデコレータを付加する。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

def decorator(func):
def inner(string):
print "<div>"

#excecute decorated
func(string)
###################

print "</div>"
return False
return inner

@decorator
def decorated(string):
print string

decorated("content1")
decorated("content2")

このスクリプトを実行したら出力は以下のように。
>>>
<div>
content1
</div>
<div>
content2
</div>

もとはただ引数を出力する関数が、デコレートされることで、出力にdivタグを付加されている。


 ぼくがGAEで使った"@login_required"は、リクエスト情報からログインしてるかを確かめる関数が書かれていたということなんだろう。わたされたオブジェクトからログイン状態を抜きだし、ログインしていれば処理続行、ログインしていなければ別処理を与えるというような。

 ちょっと似たものを書いてみる。元はオブジェクトを渡されて、オブジェクトに入っているデータを表示するだけ。そこに、オブジェクトに入っているパスワードを確認するデコレータを加える。パスワードが合致しなければ処理は行わない。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def decorator(func):
def inner(ob):
if ob.password != "pass":
print "did not match the password"
return
#excecute decorated
func(ob)
###################
return inner

class hoge:
def __init__(self, password = "none", data = "none"):
self.password = password
self.data = data

@decorator
def decorated(ob):
print ob.data

ob = hoge(password="pass", data="some string")
decorated(ob)

print "\n"
ob = hoge(data="some string")
decorated(ob)

出力は以下のようになる。
>>>
some string


did not match the password

デコレータを使えば、スクリプト中の各関数で必要な例外処理などの前処理、後処理を、それぞれの関数にわたって繰り返し描く必要がなくなる。便利なので使ってみる。
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。