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

一、装饰器是个什么鬼?

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

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

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

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

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

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

四、高阶函数

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

高阶函数的例子:

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

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

def father(name):
print('from father %s' %name)
def son():
print('from son')
def grandson():
print('from grandson')
grandson()
son() father('还是牛')

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

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

七、装饰器的基本框架

def timmer(func):
def wrapper():
print(func)
func()
return wrapper def boo():
print('你就是个傻逼!') res = timmer(boo) # 返回的是wrapper的内存地址 <function timmer.<locals>.wrapper at 0x02129420>
#print(res)
res() #是在执行wrapper 函数

八、装饰器的两种形式:

第一种 无参数的装饰器

user_list=[
{'name':'alex','passwd':''},
{'name':'linhaifeng','passwd':''},
{'name':'wupeiqi','passwd':''},
{'name':'yuanhao','passwd':''},
] current_user={'username':None,'login':False} def auth_deco(func):
def wrapper(*args,**kwargs):
if current_user['username'] and current_user['login']:
res=func(*args,**kwargs)
return res
username=input('用户名: ').strip()
passwd=input('密码: ').strip() for index,user_dic in enumerate(user_list):
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username']=username current_user['login']=True
res=func(*args,**kwargs)
return res
break
else:
print('用户名或者密码错误,重新登录') return wrapper @auth_deco
def index():
print('欢迎来到主页面') @auth_deco
def home():
print('这里是你家') def shopping_car():
print('查看购物车啊亲') def order():
print('查看订单啊亲') print(user_list)
# index()
print(user_list)
home()

第二种 含有参数的装饰器

user_list=[
{'name':'alex','passwd':''},
{'name':'linhaifeng','passwd':''},
{'name':'wupeiqi','passwd':''},
{'name':'yuanhao','passwd':''},
] current_user={'username':None,'login':False}
def auth(auth_type='file'):
def auth_deco(func):
def wrapper(*args,**kwargs):
if auth_type == 'file':
if current_user['username'] and current_user['login']:
res=func(*args,**kwargs)
return res
username=input('用户名: ').strip()
passwd=input('密码: ').strip() for index,user_dic in enumerate(user_list):
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username']=username
current_user['login']=True
res=func(*args,**kwargs)
return res
break
else:
print('用户名或者密码错误,重新登录')
elif auth_type == 'ldap':
print('巴拉巴拉小魔仙')
res=func(*args,**kwargs)
return res
return wrapper
return auth_deco #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
@auth(auth_type='ldap')
def index():
print('欢迎来到主页面') @auth(auth_type='ldap')
def home():
print('这里是你家') def shopping_car():
print('查看购物车啊亲') def order():
print('查看订单啊亲') # print(user_list)
index()
# print(user_list)
home()

最新文章

  1. 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor
  2. HDU 2295 Radar (重复覆盖)
  3. Shell 字符串常见操作
  4. 试读《基于MVC的JavaScript Web富应用开发》
  5. Hashtable 和 HashMap 的比较
  6. 转载 @html.ActionLink的几种参数格式
  7. Rsync同步工具安装文档
  8. BZOJ 3677 连珠线
  9. python插入mysql新值
  10. 取list的值
  11. EasyUIDataGrid去掉垂直滚动条
  12. 第一册:lesson sixty five.
  13. 线程GIL锁 线程队列 回调函数
  14. InnoDB中锁的算法(1)
  15. ssm项目中遇到微信用户名称带有表情,插入失败问题
  16. 悟空模式-java-原型模式
  17. Material Designer的低版本兼容实现(一)—— 简介 &amp; 目录
  18. 1-20 RHEL7的启动原理和服务控制
  19. windows 关机 重启 命令
  20. Python的print的底层实现

热门文章

  1. Java学习笔记之基础语法(顺序,条件,循环语句)
  2. dll劫持破坏360
  3. win server 2008R2 安装telnet 在VM虚拟机中
  4. 自定义的Spring Boot starter如何设置自动配置注解
  5. 玩转u8g2 OLED库,一篇就够(分篇)
  6. 让SpringBoot的jackson支持JavaBean嵌套的protobuf
  7. django-Views之request(二)
  8. js循环和调用
  9. 加上cdn后字体跨域
  10. Django实现WebSSH操作物理机或虚拟机