一、定义

器即函数

装饰即修饰,意指为其他函数添加新功能

装饰器定义:本质就是函数,功能是为其他函数添加新功能

原则:

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

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

二、装饰器=高阶函数+函数嵌套+闭包

1. 高阶函数

默认满足以下两个条件中的一个就是高阶函数:

  • 函数的传入参数是一个函数名
  • 函数的返回值是一个函数名
#高阶函数应用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增加任何新功能 函数返回值是函数名

2. 函数嵌套

在函数内部定义函数

3. 闭包

闭包:在一个作用域里放入定义变量,相当于打了一个包

三、装饰器实现

def timmer(func):
def wrapper(*args, **kwargs):
print(func)
res = func(*args, **kwargs)
return res return wrapper @timmer # test = timmer(test)
def test(name, age):
print('姓名:%s,年龄:%s' % (name, age))
return 1 msg = test('Tom', 18) # 就是在运行wrapper
print(msg)

四、应用

网站登录认证

 user_list = [
{'name': 'alex', 'passwd': ''},
{'name': 'Tom', 'passwd': ''},
{'name': 'Jerry', '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
i = 0
while i < 3:
username = input('用户名: ').strip()
passwd = input('密码: ').strip()
for user_dic in 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
else:
print('用户名或者密码错误,重新登录')
i += 1
print('请稍后重试') return wrapper @auth_deco
def index():
print('欢迎来到主页面') @auth_deco
def home():
print('这里是你家') @auth_deco
def shopping_car():
print('查看购物车啊亲') @auth_deco
def order():
print('查看订单啊亲') home()

无参装饰器

 user_list = [
{'name': 'alex', 'passwd': ''},
{'name': 'Tom', 'passwd': ''},
{'name': 'Jerry', '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
i = 0
while i < 3:
username = input('用户名: ').strip()
passwd = input('密码: ').strip()
for user_dic in 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
else:
print('用户名或者密码错误,重新登录')
i += 1
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('这里是你家') @auth(auth_type='file')
def shopping_car():
print('查看购物车啊亲') @auth(auth_type='file')
def order():
print('查看订单啊亲') order()

有参装饰器

五、类的装饰器

装饰器不仅可以对函数进行装饰,还可以装饰类

def deco(obj):
print('====')
obj.x = 1
obj.y = 2
return obj @deco
class Foo(object):
pass print(Foo.__dict__)
# {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>,
# '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}

最新文章

  1. HTML5扩展之微数据与丰富网页摘要
  2. C#与C/C++的交互
  3. 第3天作业 PoEdu MyString实现
  4. 图片轮播 js代码
  5. Flask 开发全球化应用
  6. Django 的css和js压缩插件:django_compressor
  7. Nginx作为简单代理服务器(Windows环境)
  8. 小圣求职记A:腾讯篇
  9. CentOS Linux使用crontab运行定时任务详解
  10. Python全栈【进程、线程】
  11. BandwagonHost搬瓦工VPS自建
  12. 第一章 Linux系统概述
  13. Python网络编程(1)-socket
  14. BottomNavigationBarItem fixed
  15. Transaction rolled back because it has been marked as rollback-only
  16. Linux 安装 jdk8
  17. Android 9.0新特性
  18. MvcPager帮助文档 — PagerOptions 类
  19. 组件的三大属性state,props,refs与事件处理
  20. 内部排序-&gt;插入排序-&gt;其它插入排序-&gt;2-路插入排序

热门文章

  1. Xamarin Forms 实现发送通知点击跳转
  2. PKUWC2019 Round 2 没去祭
  3. 微信小程序class封装http
  4. 深入浅出的Java网络通信
  5. Eclipse Maven问题小记
  6. koa 搭建模块化路由/层级路由
  7. 安装关系型数据库MySQL和大数据处理框架Hadoop
  8. 【转】23 个安卓重难点突破,带你吃透 Service 知识点「长达 1W+ 字」
  9. 嵌入式LINUX基础教程 第2版
  10. 浏览器中开发人员工具快速找到dom元素绑定那些JS事件