2014年5月6日火曜日

pythonのデコレータについて

pythonにデコレータについて忘れた部分があったので、メモ書き。


デコレータとは

pythonのデコレータとは関数をラップしたもの。
デコレータを使用せずに関数をラップすると以下のようになる。
def func1():
    print("func1")

def func2():
    func1()
    print("func2")
これはデコレータを使用すると以下のようになる。
def func1(func):
    def wrapper(*args, **kwargs):
        print("func1")
        func(*args, **kwargs)
    return wrapper

@func1
def func2():
    print("func2")
ただこのままだとfunc2.__name__とやったときにwrapperと表示されてしまうので,functools.wrapsを使用する。
def func1(func):
    from functools import wraps
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("func1")
        func(*args, **kwargs)
    return wrapper

@func1
def func2():
    print("func2")
こうすることでfunc2.__name__やfunc2.__doc__が失われることがなくなる。

デコレータで引数を受け取る方法

デコレータとして定義した関数を引数を受け取る関数でさらにラップすることで 引数が受け取れる。
def f1(a=None, b=None):
    def receive_func(f):
        from functools import wraps
        @wraps(f)
        def wrapper(*args, **kwargs):
            if a is not  None and b is not None:
                print("{0} {1}".format(a, b))
            print("f1")
            return f(*args, **kwargs)
        return wrapper
    return receive_func

@f1(a=1,b=2)
def f2():
    print("f2")
ここまでやるとコードの見通しがだいぶ悪くなるなぁ。。。 とりあえず今回はここまで。

0 件のコメント:

コメントを投稿