python2.4から、デコレータという概念が追加されています。
デコレータとは、GoFのデザインパターンにある名前のやつと同じく
なにかを修飾する機能を持つものです。pythonの場合は、
デコレート対象が関数およびメソッドになります。
初期状態で、@classmethod, @staticmethodというデコレータが
用意されています。また、デコレータを自作することも可能です。
しかも、やり方はとても簡単。
デコレータを使うには、関数およびメソッドの前の行にて
@付きでデコレータ名を記述します。
以下、例です。
class A(object): def __init__(self): pass @classmethod def myClassMethod(self): """クラスメソッドです。""" pass
デコレータの正体は、実はただの関数です。
ただし、引数にデコレート対象の関数オブジェクトが
渡される事以外は、普通の関数です。
渡された関数オブジェクトに対して、どのような処理を行うかは
まったくの自由です。また、最後にreturnにてコール可能な
オブジェクトを返却すればいいだけです。
以下、サンプルです。
このサンプルでは、デコレート対象の関数オブジェクトに対して
動的にdetailというフィールドを追加しています。
#!/usr/bin/env python # -*- coding: cp932 -*- # vim:set ts=4 sw=4 et ws is nowrap ft=python: def mydecorator(func_obj): """サンプルデコレータ. 該当のファンクションオブジェクトに対して、detailフィールドを 付加します。 """ code = func_obj.func_code func_obj.detail = \ "<ファイル名:%s, 関数名:%s, 引数の数:%s>" % (code.co_filename, code.co_name, code.co_argcount) return func_obj @mydecorator def myfunc(x, y): """サンプル用の関数. この関数は、mydecoratorデコレータによって デコレートされます. """ return x + y if __name__ == '__main__': # # デコレートされたデータを表示 # print myfunc.detail # # 普通にコール. # print myfunc(1, 10)
上記のソースを実行すると、myfunc関数オブジェクトには、detailというフィールドは
定義していないのに、実行時にはデコレータによって外から定義されるように
なります。
ちなみに、デコレータが返す値は、コール可能なもの(callable)なもので
あればいいので、やり方によっては全然別のオブジェクトを返す事も
可能ですね。