LoginSignup
2
1

More than 5 years have passed since last update.

デコレータの理解

Last updated at Posted at 2018-03-02

クロージャを応用して関数に機能を修飾するデコレータが使える

#デコレータ関数
def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result

    return wrapper

@print_info
def add_num(a,b):
    return a+b

r = add_num(1,2)
print(r)

>>>
start
end
3

print_info()は関数を引数にとりwrapper関数に渡す。
wrapper関数は任意の処理を行ったあと、受け取った関数を呼び出し返り値を返す。

以下の記述と同等の意味を持つ。

#デコレータ関数
def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result

    return wrapper

def add_num(a,b):
    return a+b

f = print_info(add_num)
r = f(1,2)
print(r)

>>>
start
end
3

複数のデコレータを重ねる場合は順序によって処理が変わる。

def print_info(func):
    def wrapper(*args, **kwargs):
        print('start')
        result = func(*args, **kwargs)
        print('end')
        return result

    return wrapper

#new
def print_more(func):
    def wrapper(*args, **kwargs):
        print('func:',func.__name__)
        print('args:',args)
        print('kwargs',kwargs)
        result = func(*args, **kwargs)
        return result

    return wrapper

@print_info
@print_more
def add_num(a,b):
    return a+b

r = add_num(1,2)
print(r)

>>>
start
func: add_num
args: (1, 2)
kwargs {}
end
3

デコレータの順序を逆にすると

#略

@print_more
@print_info
def add_num(a,b):
    return a+b

r = add_num(1,2)
print(r)

>>>
func: wrapper
args: (1, 2)
kwargs {}
start
end
3

処理順が変わる。

以下の記述と同等の意味を持つ


#略

def add_num(a,b):
    return a+b

f = print_info(print_more(add_num))
r = f(1,2)
print(r)

>>>
start
func: add_num
args: (1, 2)
kwargs {}
end
3

以上

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1