摘要:
本质:装饰器本质是函数
功能:为函数添加附加功能
原则:
1.不修改源代码
2.不改变原函数调用方式
构成:高阶函数+嵌套函数+闭包
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
高阶函数定义: 1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上诉条件任意一个,就是告诫函数 ''' #高阶函数之接收参数是一个函数 def foo(): print('接受的参数是一个函数名') def test(func): ##这是高阶函数 print(func) ##<function foo at 0x00000193D739C2F0>函数内存地址 func() test(foo) ##高阶函数之返回值是一个函数名 def foo1(): print('返回一个函数名') def test1(func): return func res = test1(foo1) print(res) ##函数内存地址:<function foo1 at 0x0000021248747400> res() ##加括号就可以调用函数 ##函数即变量,可以进行赋值;增加功能不改变调用方式的原理 def foo2(): print('返回一个函数名') def test2(func): return func foo2 = test2(foo2) print(foo2) foo2()
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
##增加功能,但不改变调用方式 def foo3(): ##源程序 time.sleep(3) print('这是原函数') def timer(func): ##增加附加功能程序 print('这是增加附加功能的函数') start_time = time.time() func() stop_time = time.time() print('运行时间%s'%(stop_time-start_time)) return func foo3 = timer(foo3) ##将增加功能的函数赋值给原函数名 foo3() ##调用方式不变
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#函数的嵌套:def 内再定义def def father(name): print('from father:%s'%name) def son(): print('from the son') print(locals()) ###打印该层的变量:{'name': 'alex', 'son': <function father.<locals>.son at 0x00000167705B2488>} son() father('alex') ##函数闭包(封装变量):嵌套函数变量,同级别优先,没有依次向外层找,知道找到为止 def father(name): def son(): print('嵌套第二层,没有变量赋值') def grandson(): print('嵌套第三层,有局部变量赋值') name = '同级有局部变量,优先' print('嵌套第三层:%s'%name) grandson() son() father('alex')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#装饰器的框架 高阶函数 def timmer(func): return func #高阶函数+嵌套+闭包【装饰器基本框架】 def timmer(func): ##【高阶函数:输入或返回函数名】 def wrapper(): ##【嵌套】 print(func) ##【闭包】函数即变量,同级没有,向外层找,直到找到为止 func() return wrapper #装饰器的应用(将添加功能的函数以变量形式赋给原程序名) def add_func(func): print('这是高阶函数') def qiantao(): print('这是嵌套函数:实现附加功能') func() return qiantao def origin_func(): print('这是原程序:实现原始功能') res = add_func(origin_func) res() ##1.没改变源代码 2.没改变调用方式 3.为源代码添加了附加功能 ##装饰器(语法糖) #@add_func 就相当于执行了:在需要修饰的函数前加上@add_func ''' res = add_func(origin_func) res() ''' def add_func(func): print('这是高阶函数') def qiantao(): print('这是嵌套函数:实现附加功能') func() return qiantao @add_func def origin_func(): print('这是原程序:实现原始功能') origin_func()
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
##装饰器加返回值:赋值返回 def add_func(func): print('这是高阶函数') def qiantao(): print('这是嵌套函数:实现附加功能') res = func() return '这是origin_func的返回值' return qiantao @add_func def origin_func(): print('这是原程序:实现原始功能') res = origin_func() print(res) ''' 这是高阶函数 这是嵌套函数:实现附加功能 这是原程序:实现原始功能 这是origin_func的返回值 '''
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
###装饰器带参数 def add_func(func): print('这是高阶函数') def qiantao(*args,**kwargs): print('这是嵌套函数:实现附加功能') res = func(*args,**kwargs) return res return qiantao @add_func def origin_func(name,age,gender): print('这是原程序:实现原始功能') return '姓名:%s,年龄:%s,性别:%s'%(name,age,gender) res = origin_func('alex',18,'女') print(res)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
def auth_func(func): def wrapper(*args, **kwargs): username = input('用户名:').strip() passwd = input('密码:').strip() if username == 'sb' and passwd == '123': res = func(*args, **kwargs) return res else: print('用户名或密码错误') return wrapper @auth_func def index(): print('欢迎来到京东主页') @auth_func def home(name): print('欢迎回家%s' % name) @auth_func def shopping_car(name): print('%s购物车里有【%s,%s,%s】' % (name, '被子', '文具', '玩具 ')) def order(): pass
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
###登录验证功能,登录一次,这个网站其他部分不用再次登录(全局变量) user_dic = {'username':None,'Login':False} def auth_func(func): def wrapper(*args, **kwargs): if user_dic['username'] and user_dic['Login']: res = func(*args, **kwargs) return res username = input('用户名:').strip() passwd = input('密码:').strip() if username == 'sb' and passwd == '123': user_dic['username'] = username user_dic['Login'] = passwd res = func(*args, **kwargs) return res else: print('用户名或密码错误') return wrapper @auth_func def index(): print('欢迎来到京东主页') @auth_func def home(name): print('欢迎回家%s' % name) @auth_func def shopping_car(name): print('%s购物车里有【%s,%s,%s】' % (name, '奶茶', '妹妹', '娃娃 ')) def order(): pass index() home('sb') shopping_car('sb')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
###登录验证功能,用户名和密码随用户注册而来 user_list = [ {'name':'alex','passwd':'123'}, {'name':'jhon','passwd':'123'}, {'name':'jack','passwd':'123'}, {'name':'lilei','passwd':'123'}, ] current_dic = {'username':None,'Login':False} ##记录用户当前状态 def auth_func(func): def wrapper(*args, **kwargs): if current_dic['username'] and current_dic['Login']: res = func(*args, **kwargs) return res username = input('用户名:').strip() passwd = input('密码:').strip() for user_dic in user_list: if username == user_dic['name'] and passwd == user_dic['passwd']: current_dic['username'] = username current_dic['Login'] = passwd res = func(*args, **kwargs) return res else: print('用户名或密码错误') return wrapper @auth_func def index(): print('欢迎来到京东主页') @auth_func def home(name): print('欢迎回家%s' % name) @auth_func def shopping_car(name): print('%s购物车里有【%s,%s,%s】' % (name, '玩具', '奶粉', '文具 ')) def order(): pass index() home('sb') shopping_car('sb')