[python]戻り関数とアクセサリ
2957 ワード
戻り関数
関数を返します:関数は結果としてe.gを返します:
>呼び出しのたびに、同じパラメータが入力された場合でも、新しい関数が返されます.
デコレータ
補足:関数オブジェクトにはnameプロパティe.gがあります.
装飾の書き方:@funcName e.g:
decoratorは実質的に関数を返すので、元のtest()関数は依然として存在しますが、同じ名前のtest変数が新しい関数を指しているだけで、test()を呼び出すとprint_で新しい関数が実行されます.caller()関数で返されるwrapper()関数.wrapper()関数のパラメータ定義は(*args,**kw)であるため、wrapper()関数は任意のパラメータの呼び出しを受け入れることができる.wrapper()関数では、まずログを印刷し、元の関数を呼び出します.だから、@print_callerは実行に相当します.
印刷関数の実行前後時間のexample:
上記のいくつかの例は、decoratorがパラメータを伝達する必要がない場合であり、decoratorがパラメータを伝達する必要がある場合は、decoratorを返す高次関数e.gを記述する必要があります.
実質的に3層のネスト、@add_textは実行に相当します.
*decoratorの本質的なネスト戻り関数は、プロトタイプポインタが変化することを招き、nameなどの属性も変化し、上述のnameがtestからwrapperになるように、理論的にwrapperを追加すべきである.name = func.name、プロトタイプポインタを元の関数にポインタしますが、Pythonにはfunctoolsが内蔵されています.wrapsはこの処理をしました
関数を返します:関数は結果としてe.gを返します:
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
f = lazy_sum(1,2) # lazy_sum , sum f
f() #
# lazy_sum(1,2)()
3
>呼び出しのたびに、同じパラメータが入力された場合でも、新しい関数が返されます.
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
f1==f2
>>>False
デコレータ
補足:関数オブジェクトにはnameプロパティe.gがあります.
def now():
print('2015-3-25')
f = now
now.__name__
>>>'now'
f.__name__
>>>'now'
装飾の書き方:@funcName e.g:
def print_caller(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
def test():
print('test')
@print_caller
test()
>>>call test():
>>>test
decoratorは実質的に関数を返すので、元のtest()関数は依然として存在しますが、同じ名前のtest変数が新しい関数を指しているだけで、test()を呼び出すとprint_で新しい関数が実行されます.caller()関数で返されるwrapper()関数.wrapper()関数のパラメータ定義は(*args,**kw)であるため、wrapper()関数は任意のパラメータの呼び出しを受け入れることができる.wrapper()関数では、まずログを印刷し、元の関数を呼び出します.だから、@print_callerは実行に相当します.
test = print_caller(test)
印刷関数の実行前後時間のexample:
def metric(func):
def decorator(*args, **kw):
print('start:%s' % int(time.time()))
time.sleep(2)
r = func(args, **kw)
print('end:%s' % int(time.time()))
return r
return decorator
@metric
def test(a):
print('test')
test()
>>>start:1554695731
>>>test
>>>end:1554695733
上記のいくつかの例は、decoratorがパラメータを伝達する必要がない場合であり、decoratorがパラメータを伝達する必要がある場合は、decoratorを返す高次関数e.gを記述する必要があります.
def add_text(text):
def decorator(func):
def wrapper(*args, **kw):
print('text:%s' % text)
r = func(args, **kw)
return r
return wrapper
return decorator
@add_text('miao')
def test(a):
print('test')
>>>text:miao
>>>test
実質的に3層のネスト、@add_textは実行に相当します.
test = add_text('miao')(test)
*decoratorの本質的なネスト戻り関数は、プロトタイプポインタが変化することを招き、nameなどの属性も変化し、上述のnameがtestからwrapperになるように、理論的にwrapperを追加すべきである.name = func.name、プロトタイプポインタを元の関数にポインタしますが、Pythonにはfunctoolsが内蔵されています.wrapsはこの処理をしました
import functools
#
def print_caller(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
#
def add_text(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('text:%s' % text)
r = func(args, **kw)
return r
return wrapper
return decorator