今天把学过的装饰器的知识进行回顾一下,说到装饰器,第一反应就是这个东西呢就是用来装逼的,为啥这样说呢,是应为没有这个东西照样可以干活,大部分工作都是可以做的,不管咋样还是把学过的装逼器梳理一下吧。

一、装饰器是个什么鬼?

装饰的意思呢,就是修饰,装点的意思可以给别的函数添加新的功能,器呢就是函数的意思,so 装饰器即是为别的函数添加新的功能的函数。

二、作为一个装饰器,他、它有什么样的规则呢?

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

三、如何实现一个装饰器呢?

要实现一个可以使用的装饰器就需要满足:装饰器=高阶函数+函数嵌套+闭包

四、高阶函数

上节介绍完了什么是高阶函数,只要满足:1.函数可以接受函数名当参数进行传递 2.函数的返回值可以返回一个函数名  只要能够满足上面的任何一条就认为构成的这个函数是高阶函数

高阶函数的例子:

  1. def foo():
  2. print('我的函数名作为参数传给高阶函数')
  3. def gao_jie1(func):
  4. print('我就是高阶函数1,我接收的参数名是%s' %func)
  5. func()
  6.  
  7. def gao_jie2(func):
  8. print('我就是高阶函数2,我的返回值是%s' %func)
  9. return func
  10.  
  11. gao_jie1(foo)
  12. gao_jie2(foo)
    输出的结果是:
    我就是高阶函数1,我接收的参数名是<function foo at 0x006896A8>
    我的函数名作为参数传给高阶函数
    我就是高阶函数2,我的返回值是<function foo at 0x006896A8>
  1. #高阶函数应用1:把函数当做参数传给高阶函数
  2. import time
  3. def foo():
  4. print('from the foo')
  5.  
  6. def timmer(func):
  7. start_time=time.time()
  8. func()
  9. stop_time=time.time()
  10. print('函数%s 运行时间是%s' %(func,stop_time-start_time))
  11. timmer(foo)
  12. #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
  13.  
  14. 把函数当做参数传给高阶函数
  1. #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
  2. import time
  3. def foo():
  4. print('from the foo')
  5.  
  6. def timmer(func):
  7. start_time=time.time()
  8. return func
  9. stop_time=time.time()
  10. print('函数%s 运行时间是%s' %(func,stop_time-start_time))
  11. foo=timmer(foo)
  12. foo()
  13. #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
  14.  
  15. 函数返回值是函数名

五、函数嵌套(就是函数中还有定义函数)

  1. def father(name):
  2. print('from father %s' %name)
  3. def son():
  4. print('from son')
  5. def grandson():
  6. print('from grandson')
  7. grandson()
  8. son()
  9.  
  10. father('还是牛')

六、闭包:(在一个作用域中放入的定义变量,就像打了一个包)

  1. #闭包的概念:闭就是封装的意思,就是把变量分装起来;包:就是层的意思,与之前作用域意思是一样的。
  2. #grandson中的变量有name(形式参数);son中的变量有grandson(函数名也是变量);father中的变量有:name(形式参数) son
  3. def father(name):
  4. print('from the father %s' %(name))
  5. def son():
  6. print('from the son')
  7. def grandson():
  8. print('from the grandson %s'%(name))
  9. grandson()
  10. son()
  11.  
  12. father('SB')

七、装饰器的基本框架

  1. def timmer(func):
  2. def wrapper():
  3. print(func)
  4. func()
  5. return wrapper
  6.  
  7. def boo():
  8. print('你就是个傻逼!')
  9.  
  10. res = timmer(boo) # 返回的是wrapper的内存地址 <function timmer.<locals>.wrapper at 0x02129420>
  11. #print(res)
  12. res() #是在执行wrapper 函数

八、装饰器的两种形式:

第一种 无参数的装饰器

  1. user_list=[
  2. {'name':'alex','passwd':''},
  3. {'name':'linhaifeng','passwd':''},
  4. {'name':'wupeiqi','passwd':''},
  5. {'name':'yuanhao','passwd':''},
  6. ]
  7.  
  8. current_user={'username':None,'login':False}
  9.  
  10. def auth_deco(func):
  11. def wrapper(*args,**kwargs):
  12. if current_user['username'] and current_user['login']:
  13. res=func(*args,**kwargs)
  14. return res
  15. username=input('用户名: ').strip()
  16. passwd=input('密码: ').strip()
  17.  
  18. for index,user_dic in enumerate(user_list):
  19. if username == user_dic['name'] and passwd == user_dic['passwd']:
  20. current_user['username']=username
  21.  
  22. current_user['login']=True
  23. res=func(*args,**kwargs)
  24. return res
  25. break
  26. else:
  27. print('用户名或者密码错误,重新登录')
  28.  
  29. return wrapper
  30.  
  31. @auth_deco
  32. def index():
  33. print('欢迎来到主页面')
  34.  
  35. @auth_deco
  36. def home():
  37. print('这里是你家')
  38.  
  39. def shopping_car():
  40. print('查看购物车啊亲')
  41.  
  42. def order():
  43. print('查看订单啊亲')
  44.  
  45. print(user_list)
  46. # index()
  47. print(user_list)
  48. home()

第二种 含有参数的装饰器

  1. user_list=[
  2. {'name':'alex','passwd':''},
  3. {'name':'linhaifeng','passwd':''},
  4. {'name':'wupeiqi','passwd':''},
  5. {'name':'yuanhao','passwd':''},
  6. ]
  7.  
  8. current_user={'username':None,'login':False}
  9. def auth(auth_type='file'):
  10. def auth_deco(func):
  11. def wrapper(*args,**kwargs):
  12. if auth_type == 'file':
  13. if current_user['username'] and current_user['login']:
  14. res=func(*args,**kwargs)
  15. return res
  16. username=input('用户名: ').strip()
  17. passwd=input('密码: ').strip()
  18.  
  19. for index,user_dic in enumerate(user_list):
  20. if username == user_dic['name'] and passwd == user_dic['passwd']:
  21. current_user['username']=username
  22. current_user['login']=True
  23. res=func(*args,**kwargs)
  24. return res
  25. break
  26. else:
  27. print('用户名或者密码错误,重新登录')
  28. elif auth_type == 'ldap':
  29. print('巴拉巴拉小魔仙')
  30. res=func(*args,**kwargs)
  31. return res
  32. return wrapper
  33. return auth_deco
  34.  
  35. #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
  36. #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
  37. @auth(auth_type='ldap')
  38. def index():
  39. print('欢迎来到主页面')
  40.  
  41. @auth(auth_type='ldap')
  42. def home():
  43. print('这里是你家')
  44.  
  45. def shopping_car():
  46. print('查看购物车啊亲')
  47.  
  48. def order():
  49. print('查看订单啊亲')
  50.  
  51. # print(user_list)
  52. index()
  53. # print(user_list)
  54. home()

Python 基础 装饰器的更多相关文章

  1. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  2. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

  3. python 基础——装饰器

    python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...

  4. day5学python 基础+装饰器内容

    基础+装饰器内容 递归特性# 1.必须有一个明确的结束条件# 2.每次进入更深一层递归时,问题规模相比上次递归应有所减少# 3.递归效率不高 def run(n): print(n) if int(n ...

  5. Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle

    目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...

  6. python基础 (装饰器,内置函数)

    https://docs.python.org/zh-cn/3.7/library/functions.html 1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使 ...

  7. python基础-装饰器,生成器和迭代器

    学习内容 1.装饰器 2.生成器 3.迭代器 4.软件目录结构规范 一:装饰器(decorator) 1.装饰器定义:本质就是函数,用来装饰其他函数,即为其他函数添加附加功能. 2.装饰器原则:1)不 ...

  8. python基础===装饰器@property 的扩展

    以下来自Python 3.6.0 Document: class property(fget=None, fset=None, fdel=None, doc=None) Return a proper ...

  9. <Python基础>装饰器的基本原理

    1.装饰器 所谓装饰器一般是对已经使用(上线)的函数增加功能. 但是因为一般的大公司的严格按照开放封闭原则(对扩展是开放的,对修改是封闭的),不会让你修改原本的函数. 装饰器就是在不改变原本的函数且不 ...

  10. python基础-装饰器

    一.什么是装饰器 装饰器本质就是函数,功能是为其他函数附加功能 二.装饰器遵循的原则 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 三.实现装饰器的知识储备 装饰器=高阶函数+函数嵌套 ...

随机推荐

  1. Ubuntu16.04 安装apache+mysql+php(LAMP)

    记录下ubuntu环境下安装apache+mysql+php(LAMP)环境. 0x01安装apache sudo apt-get update sudo apt-get install apache ...

  2. web项目中登陆超时的功能实现(基于C#)

    当我们登陆进网站后,中途去看别的东西,没有再与该网站的服务器交互,就会弹出一个js窗口,登陆超时请重新登陆,并跳转到登陆页面. 步骤1.实现原理,在web.config中配置session的超时时间, ...

  3. [POJ3107] Godfather - 暴力枚举(树的重心)

    Godfather Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8728   Accepted: 3064 Descrip ...

  4. 21.Nginx代理缓存

    1.环境准备 操作系统 应用服务 外网地址 内网地址 CentOS7.6 LB01 10.0.0.5 172.16.1.5 CentOS7.6 Web01 10.0.0.7 172.16.1.7 2. ...

  5. 06 Node.js学习笔记之自动路由

    在以往客户端请求的文件,我们都得判断匹配才能返回相应的数据,其实我们可以设置一个自动路由,就可以不用每次去判断用户访问的是那个文件了 //1.载入http和fs模块 var http=require( ...

  6. Mybaits 源码解析 (一)----- 搭建一个mybatis框架(MyBatis HelloWorld)

    源码分析之前先搭一个mybatis的demo,这个在看源码的时候能起到了很大的作用,因为在看源码的时候,会恍然大悟,为什么要这么配置,为什么要这么写.(老鸟可以跳过这篇) 开发环境的准备 创建mave ...

  7. mp-vue实现小程序回顶操作踩坑,wx.pageScrollTo使用无效填坑

    本来项目都写的差不多了,测试测着侧着就冒出了新的想法,我因为做的是问卷,因此会有用户必答题未答完的可能存在,本来市场部给的需求就是做一个弹窗就好了,她说想要做出跳回到用户未答的第一道题,好吧,既然都这 ...

  8. GStreamer基础教程11 - 与QT集成

    摘要 通常我们的播放引擎需要和GUI进行集成,在使用GStreamer时,GStreamre会负责媒体的播放及控制,GUI会负责处理用户的交互操作以及创建显示的窗口.本例中我们将结合QT介绍如何指定G ...

  9. The usage of Markdown---引用

    目录 1. 序言 2. 引用与嵌套引用 3. 列表中的引用 更新时间:209.09.14 1. 序言   在本篇,我们来仔细谈一下Markdown的引用. 2. 引用与嵌套引用   在Markdown ...

  10. Java基础(十三)内部类(inner class)

    1.内部类是定义在另一个类中的类.使用内部类的原因有: 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据 内部类可以对同一个包中的其他类隐藏起来 当想要定义一个回调函数且不想编写大量代码 ...