1. decorator 기본구성
A: enclosing func
B: nested func
C: func as arg
2. 작동
Call C
Pass C into A as arg
A return B
B do something using C
3. code example
step1
1 2 3 4 5 6 7 8 9 10 11 12 def uppercase_decorator (func) : def wrapper () : return func().upper() return wrapper @uppercase_decorator def say () : return 'hello there' say()
'HELLO THERE'
step2
decorator which accept args
1 2 3 4 5 def dec_with_args (func) : def nested_accept_args (arg1, arg2) : print('ars: {}, {}' .format(arg1, arg2)) func(arg1, arg2) return nested_accept_args
1 2 3 4 5 @dec_with_args def cities (first, second) : print('cities: {}, {}' .format(first, second)) cities('sun' , 'moon' )
ars: sun, moon
cities: sun, moon
step3
decorator which accept as many args as user would like
1 2 3 4 5 6 7 8 9 10 11 12 13 def dec_pass_arbitrary_args (func) : def wrapper (*args, **kwargs) : print('the positional args are' , args) print('the keword args are' , kwargs) func(*args) return wrapper @dec_pass_arbitrary_args def func_with_args (a, b, c) : print(a, b, c) func_with_args(1 ,2 ,3 )
the positional args are (1, 2, 3)
the keword args are {}
1 2 3
1 2 3 4 5 @dec_pass_arbitrary_args def func_with_kwargs () : print('this has keyword args' ) func_with_kwargs(name='Roy' , age='12' )
the positional args are ()
the keword args are {'name': 'Roy', 'age': '12'}
this has keyword args
step4
dec within wrapper passing dec_args
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def dec_wrapper (*dec_args) : def dec (func) : "decorator we code above" def wrapper (*func_args) : print("dec positional args: " , dec_args) print("func positional args: " , func_args) return func(*func_args) return wrapper return dec @dec_wrapper('dec1', 'dec2') def func1 (*args) : print('this is from func1' , args) func1('func1' , 'func2' )
dec positional args: ('dec1', 'dec2')
func positional args: ('func1', 'func2')
this is from func1 ('func1', 'func2')
step5
decorator which measure the execution time
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import timedef timeit (func) : def wrapper (*args, **kwargs) : print('strat timeit' ) ts = time.time() result = func(*args) te = time.time() print(func.__name__, te-ts) return result return wrapper @timeit def multiply_nums (*num) : print('start multiply func' ) i = 1 for j in num: i *= j return i res = multiply_nums(1 ,2 ,3 ) print(res)
strat timeit
start multiply func
multiply_nums 4.982948303222656e-05
6