Python閉包と装飾器の原理及び実例解析
一、閉め切ってください
クローズドは、関数に相当します。他の関数を入れ子して返します。コードは以下の通りです
装飾器:関数testを変数として登録した装飾関数deco-->が装飾操作を行った後、変数は関数test()に伝えられました。例えば、装飾器の効果はtest=test-1で、test関数がdecoで飾られた後、testを呼び出して実行するのはtest=test-1です。
1、装飾器はクローズドの原理を利用して、装飾器がクローズドに入ってくるパラメータを関数として区別します。変数ではありません。
注:実は飾り器の中で、関数は変数です。
前のバージョンでは、装飾器+関数を定義する際に、装飾関数の文言が実行されます。
呼び出されていないときに実行しないためには、もう一つの関数を入れ替える必要があります。
小包関数では、パラメータ形式は、*arg、*kwargに設定されており、より柔軟な関数になります。
test関数パラメータ形式を変更すると、装飾器で同時に変更する必要はありません。
ある時、私達はある飾り器の中に括弧が付いています。その原因は上記の飾り器の外にもう一つの関数が付いているからです。
パラメータ付き装飾器(飾り器に括弧、パラメータ付き)
クローズドは、関数に相当します。他の関数を入れ子して返します。コードは以下の通りです
def func(name): #
def inner_func(age): #
print('name: ', name, ', age: ', age)
return inner_func # ,
bb = func('jayson') # func , inner_func
bb(28) # func , ,
>>
name: jayson , age: 28
二、飾り器装飾器:関数testを変数として登録した装飾関数deco-->が装飾操作を行った後、変数は関数test()に伝えられました。例えば、装飾器の効果はtest=test-1で、test関数がdecoで飾られた後、testを呼び出して実行するのはtest=test-1です。
1、装飾器はクローズドの原理を利用して、装飾器がクローズドに入ってくるパラメータを関数として区別します。変数ではありません。
注:実は飾り器の中で、関数は変数です。
def deco(func): # func 。
print('decoration')
return func
def test():
print('test_func')
test = deco(test) # 。 deco , test
>>
# deco
decoration
test() #
>>
test_func
2、以上のコードは
def deco(func): # func 。
print('decoration')
return func
@deco # test = deco(test), test
def test():
print('test_func')
>>
# deco
decoration
test() #
>>
test_func
3、装飾器(簡易版)
def deco(func): # func
print('decoration')
return func
@deco # 。
def test():
print('test_func')
# , deco(test)
>>
decoration
# test, test
test()
>>
test_func
3、飾り器(アップグレード版)前のバージョンでは、装飾器+関数を定義する際に、装飾関数の文言が実行されます。
呼び出されていないときに実行しないためには、もう一つの関数を入れ替える必要があります。
def deco(func):
print('decoration') # func ,
def wrapper(): # , wrapper
print('execute') # func ,
func() #
return wrapper # wrapper func, func()
@deco # : 。 func deco(), deco
def test():
print('test_func')
>>
decoration
# test
test()
>>
execute
test_func
注意:Fnc関数自体に戻り値がある場合は、同様に小包関数に戻ります。
def deco(func):
print('decoration')
def wrapper():
print('execute')
a = func() # ,
print('done')
return a # func
return wrapper
@deco
def test():
print('test_func')
return 5 #
>>
decoration
# test
test()
>>
execute
test_func
done
# test
3、装飾器(進歩版)小包関数では、パラメータ形式は、*arg、*kwargに設定されており、より柔軟な関数になります。
test関数パラメータ形式を変更すると、装飾器で同時に変更する必要はありません。
import time
def deco(func):
def inner(*arg, **kwarg): #
begin_time = time.time()
time.sleep(2)
a = func(*arg, **kwarg) # ,
end_time = time.time()
print(' :', end_time - begin_time)
return a
return inner
@deco
def test(a):
print('test function:', a)
return a
#
test(5)
>>
test function: 5
: 2.0003252029418945
# 5
4、高次版ある時、私達はある飾り器の中に括弧が付いています。その原因は上記の飾り器の外にもう一つの関数が付いているからです。
import time
def outer(): # , 。(outer )
def deco(func): # ,
def inner(*arg, **kwarg):
begin_time = time.time()
time.sleep(2)
a = func(*arg, **kwarg)
end_time = time.time()
print(' :', end_time - begin_time)
return a
return inner
return deco # :
@outer() # , outer() , test
def test(a):
print('test function:', a)
return a
test(4)
>>
test function: 4
: 2.000566005706787
# 4
5、高次終結版パラメータ付き装飾器(飾り器に括弧、パラメータ付き)
import time
def outer(choose): #
if choose==1: # choose ,
def deco(func):
def inner(*arg, **kwarg):
print('decoration1')
begin_time = time.time()
time.sleep(2) # 2s
a = func(*arg, **kwarg)
end_time = time.time()
print(' 1:', end_time - begin_time)
return a
return inner
return deco
else:
def deco(func):
def inner(*arg, **kwarg):
print('decoration2')
begin_time = time.time()
time.sleep(5) # 5s
a = func(*arg, **kwarg)
end_time = time.time()
print(' 2:', end_time - begin_time)
return a
return inner
return deco
@outer(1) # outer ,
def test1(a):
print('test function1:', a)
return a
@outer(5) #
def test2(a):
print('test function2:', a)
return a
# 2 (2 , )
test1(2) # test1
>>
decoration1
test function1: 2
1: 2.000072717666626 # 2
# test1
test2(4) # test2
>>
decoration2
test function2: 4
2: 5.000797986984253 # 5
# test2
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。