装饰器
通用装饰器、带参数的装饰器、函数使用多个装饰器、解除装饰器的作用(装饰器有副作用)
from functools import wraps
#装饰器:本质上是一个函数,在不改变原函数和调用的情况下,可以给原函数的功能进行扩展
#开闭原则:原函数不能变,调用也不能变,对扩展开发,对修改封闭
def f1(x):
return x*x
def func_new(func):
def fn(j):
print('1'*10)
#func(j)
return func(j)
return fn
f1 = func_new(f1)
print(f1(10)) #None,因为func(j)处没有返回值
def func_new1(func):
def fn(j):
print('1'*10)
#func(j)
return func(j)
return fn
@func_new1
def f1(x):
return x*x
print(f1(10))
#装饰器的写法
def decorator(func):
def inner():
print('-'*10)
func()
return inner
@decorator
def show(): #此处的show相当于inner
print('abc')
show()
#通用装饰器
def decorator(func):
def inner(*args, **kwargs):
print('-'*10)
return func(*args, **kwargs)
return inner
@decorator
def sum_num(num1, num2):
return num1+num2
@decorator
def f(num1, num2):
return num1 * num2
print(sum_num(1, 2))
print(f(2,3))
#带有参数的装饰器
#实现部分函数前面打印---,部分函数前面打印***
#定义时,再包装一层
def decorator2(char):
def decorator1(func):
def inner(*args, **kwargs):
print(char*10)
return func(*args, **kwargs)
return inner
return decorator1
@decorator2('*')
def sum_num1(num1, num2):
return num1+num2
print(sum_num1(3,4))
#函数使用多个装饰器
def decorator3(func):
def inner3():
print('-'*30)
func() #aa
return inner3
def decorator4(func):
def inner4():
print('*'*30)
func() #bb
return inner4
@decorator4 #show = decorator4(decorator3(show)) -->decorator4.inner4
@decorator3 #show = decorator3(show) --> decorator3.inner3
def show():
print('aaaaa')
show() # 先打印---,再打印***,
# decorator4(decorator3(show))
# show传到 decorator3中的func,返回inner3,inner3传到 decorator4中的func,也就是说#bb处是inner3,返回inner4
#穿衣服,穿一层,再在外面套一层
#解除装饰器的作用
def decorator(func):
@wraps(func)
def inner(num1, num2):
'''inner'''
print('正在计算')
func(num1, num2)
return inner
@decorator
def sum_num(num1, num2):
'''sum_num'''
print(num1+num2)
sum_num(1,3)
#装饰器有副作用,改变原有函数的指向
print(sum_num.__doc__) #打印函数的文档说明,结果为inner;添加@wraps(func)后,结果为sum_num
sum_num.__wrapped__(1,3)#调用原有函数,装饰器失效