Python階段の装飾器
4780 ワード
1.最も基本的な装飾器装飾器の基本的なやり方:関数が進み、関数が出る.関数名はパラメータとして装飾器に入力、関数は:装飾器は関数を返す.
装飾器は断面プログラミングに対する思想(AOP)を体現し、中間部品と同じである.パラメータ付き装飾器 パラメータ付きの装飾器は、最も簡単な装飾器にもう一つの関数を組み合わせて、追加のパラメータを受信する.
2.アクセサリー
クラス装飾器を実現するには、クラスにパラメータ付きクラス装飾器 パラメータ付きクラス装飾器は、パラメータをinitから伝達するものであり、関数はcallから伝達され、call方法には内部関数が必要である.
3.多層装飾器
多層装飾器は中から外へ実行する.
4.練習問題練習1:timer装飾器を書いて、装飾関数に呼び出されるのにどれくらいの時間がかかるかを計算して、時間を に印刷します.練習2:Retry装飾器 を書く
装飾器は断面プログラミングに対する思想(AOP)を体現し、中間部品と同じである.
from functools import wraps
def deco(func):
# , func .
@wraps(func)
def inner(*args, **kwargs):
"""
this is a inner function
"""
# func
print('decorating...')
result = func(*args, **kwargs)
return result
return inner
# @ python .
@deco
def foo(x, y):
"""
return x ** y
"""
return x ** y
foo(2, 10)
# @ , func deco, foo = deco(func)
# foo deco
foo_ = deco(foo)(2, 10)
# , __doc__, __name__
# functools wraps docstring name
print(foo.__name__) # foo
print(foo.__doc__) # '
return x ** y
'
from functools import wraps
def limit_output(max_value):
def deco(func):
# , func .
@wraps(func)
def inner(*args, **kwargs):
"""
this is a inner function
"""
# func
print('decorating...')
result = func(*args, **kwargs)
if result > max_value:
return ' , '
return result
return inner
return deco
@limit_output(10000000000000000000000)
def foo(x,y):
"""
return x ** y
"""
return x ** y
foo(20,10)
out:decorating...
10240000000000
foo(20, 10000)
out:decorating...
' , '
2.アクセサリー
クラス装飾器を実現するには、クラスに
__call__
の方法を実現させなければならない.class Deco:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
# func
result = self.func(*args, **kwargs)
print('Class Deco...')
return result
#
@Deco
def foo(x,y):
return x ** y
foo(2,3)
out:Class Deco...
8
class Deco:
def __init__(self, max_value):
self.max_value = max_value
def __call__(self, func):
def inner(*args, **kwargs):
result = func(*args, **kwargs)
if result > self.max_value:
return ' .'
else:
return result
return inner
#
@Deco(10000000000000)
def foo(x,y):
return x ** y
foo(2,3)
out:8
foo(2,2000)
out:' .'
3.多層装飾器
多層装飾器は中から外へ実行する.
def deco1(func):
print('enter deco1...')
def inner1(*args, **kwargs):
print('enter inner1...')
return func(*args, **kwargs)
print('exiting deco1...')
return inner1
def deco2(func):
print('enter deco2...')
def inner2(*args, **kwargs):
print('enter inner2...')
return func(*args, **kwargs)
print('exiting deco2...')
return inner2
def deco3(func):
print('enter deco3...')
def inner3(*args, **kwargs):
print('enter inner3...')
return func(*args, **kwargs)
print('exiting deco3...')
return inner3
#
@deco1
@deco2
@deco3
def foo(x,y):
return x ** y
foo(2,3)
enter deco3...
exiting deco3...
enter deco2...
exiting deco2...
enter deco1...
exiting deco1...
8
4.練習問題
import time
from funfunctools import wraps
def timer(func):
@wraps(func) # docstring
def wrap(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(start - end)
return result
return wrap
import time
class retry(object):
def __init__(self, max_retries=3, wait=0, exceptions=(Exception,)):
self.max_retries = max_retries
self.exceptions = exceptions
self.wait = wait
def __call__(self, func):
def wrapper(*args, **kwargs):
for i in range(self.max_retries + 1):
try:
result = func(*args, **kwargs)
except self.exceptions:
time.sleep(self.wait)
continue
else:
return result
return wrapper