动态地给对象添加一些额外的职责,就增加功能来说,装饰模式比生产子类更加灵活
Component 是定义一个对象接口,可以给这些对象动态地添加职责。concreteComponent是定义一个具体对象,也可以给这个对象添加一些职责。decorator,装饰抽象类,继承
l component,从外类来扩展component类的功能,但对于component来说,是无需知道decorator存在的,至于concretedecorator就是具体的装饰对象,起到给component添加职责的功能
import time
def dumpy_decorator(f):
def wrap_f(*args):
print("*" * 44)
print('Function to be decorated:', f.__name__)
print('nested wrapping function: ', wrap_f.__name__)
print("*" * 44)
print("ProfilingDecorator called")
start_time = time.time()
resutl = f(*args)
end_time = time.time()
print(f"""{end_time-start_time} elapsed""")
print("ProfilingDecorator called over")
return resutl
print('s')
# wrap_f.__name__=f.__name__
# wrap_f.__doc__=wrap_f.__doc__
return wrap_f
@dumpy_decorator
def fib(n):
print('inside fib')
if n < 2:
return
fibprev = 1
fib = 1
for num in range(2, n):
fibprev, fib = fib, fibprev + fib
return fib
if __name__ == '__main__':
print('wrapped function:', fib.__name__)
res = fib(77)
print(res)
结果
此函数装饰器导致函数的元信息改变
python标准库包含了一个模块,它允许保留__doc__和__name__的值不被改变
修改:
import time
from functools import wraps
def dumpy_decorator(f):
@wraps(f)
def wrap_f(*args):
print("*" * 44)
print('Function to be decorated:', f.__name__)
print('nested wrapping function: ', wrap_f.__name__)
print("*" * 44)
print("ProfilingDecorator called")
start_time = time.time()
import time
class ProfilingDecorator():
def __init__(self, f):
print('ProfilingDecorator initiated')
self.f = f
def __call__(self, *args, **kwargs):
print("ProfilingDecorator called")
start_time = time.time()
resutl = self.f(*args)
end_time = time.time()
print(f"""{end_time-start_time} elapsed""")
print("ProfilingDecorator called over")
return resutl
class ToHTMLDecorator():
def __init__(self,f):
print('html decorated inited')
self.f=f
def __call__(self, *args, **kwargs):
print('html decorated called')
res=self.f(*args)
print('html decorated over')
return "{}".format(res)
@ToHTMLDecorator
@ProfilingDecorator
def fib(n):
print('inside fib')
if n < 2:
return
fibprev = 1
fib = 1
for num in range(2, n):
fibprev, fib = fib, fibprev + fib
return fib
if __name__ == '__main__':
n = 77
res = fib(n)
print(f'''the result is {res}''')
from functools import wraps
import time
def profiling_decorator_with_unit(unit):
def profile_decorator(f):
@wraps(f)
def wrap_f(*args):
start_time = time.time()
resutl = f(*args)
end_time = time.time()
if unit == 'seconds':
print(f"""{(end_time - start_time)/1000} elapsed""")
else:
print(f"""{(end_time - start_time) } elapsed""")
return resutl
return wrap_f
return profile_decorator
@profiling_decorator_with_unit('else')
def fib(n):
print('inside fib')
if n < 2:
return
fibprev = 1
fib = 1
for num in range(2, n):
fibprev, fib = fib, fibprev + fib
return fib
if __name__ == '__main__':
res = fib(77)
print(res)