- python中装饰器是为了从已经存在的函数体上添加新功能,但是不对原函数体做修改。
- 函数能够被修饰的原因是因为函数能够作为参数传给另一个函数,且函数A还可以将函数B作为其返回值。
案例一:函数能够作为参数传给另一个函数
def func1(a,b): print('[函数func1]正在执行') return a+b def func2(func,c,d): print('[函数func1]正在执行') return func(c,d) print(func1(1,2)) print(func2(func1,1,2))
# 在一个已经实现1-100的求和功能的函数上,外加功能进行性能测试。 import time # 测试函数 def inner(func): def outer(*args, **kwargs): start1 = time.time() result = func(*args, **kwargs) end1 = time.time() print(f'程序执行花费{end1 - start1}秒') return result print(outer) return outer # 功能函数 def numSum(start, end): total = 0 for i in range(start, end + 1): total += i return total numSum = inner(numSum) # 函数numSum等于变量numSum传递给形参func,inner执行,先打印outer变量代表的函数,再将outer函数返回,重新给numSum赋值 print(numSum) # 打印numSum,等价于打印outer print(numSum(1, 100))# 调用numSum等于调用outer变量等于调用outer函数 # 功能函数 @inner def numSum1(start, end): total = 0 for i in range(start, end + 1): total += i return total print(numSum1(1, 50))
传参1和100,因为装饰器是具有通用性的,所以一个装饰器可以借用给任何函数,所有的函数传参不一定一致,所以使用不定长参数*args和**kwargs接受参数。
在outer函数内部有调用了func函数,func函数就是一开始的numSum,将传递的所有参数(*args,**kwargs)再传递给func函数,此时才开始真正的调用功能函数numSum
最终既能得到功能函数应该得到的结果,有能够测试成功功能函数的性能。
可以将测试函数inner写为语法糖的形式:@测试函数名
有参装饰器可以在函数体执行功能时在多做验证(比如web权限验证)
# 可以在函数体执行功能时在多做验证(Web权限验证) def limit(kind): def inner(func): def outer(*args, **kwargs): result = func(*args, **kwargs) if result == '登陆成功': if kind == '会员': return result, '尊敬的vvvvvvvip用户' else: return result, '感谢白嫖用户登录' else: return result return outer return inner # 语法糖的参数是登录账号时程序同时验证账号权限得到的结果 @limit('非会员') def userLogin(username, pwd): if username == 'admin' and pwd == '123456': return '登陆成功' else: return '登录失败' print(userLogin('admin', '123457'))