1、装饰器本质

装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

2、装饰器函数

假设要写一个输出函数执行时间的装饰器
def timer(func):
def inner():
start = time.time() #这里需要导入time模块
func()
end = time.time()
print(end - start) def func():
time.sleep(2) #延长函数的执行时间,方便观察
print('----') func = timer(func)
func()  #实质是已经变成了inner函数

3、语法糖

如果按2写,每次都要写func = timer(func),并且比较不方便,这时候可以使用@语法来进行装饰

#timer和func函数还是按照2中的
@timer
def func():... #@timer其实就是相当于执行了func = timer(func)

4、装饰有返回值的函数的装饰器

有时候函数是有返回值的,我们就可以这么做

def timer(func):
def inner():
start = time.time()
ret = func() #通过赋值给ret来接收func函数的返回值
end = time.time()
print(end-start)
return ret #因为装饰完的函数其实就是inner函数,所以通过inner的return,就可以将func函数的返回值返回回去
return inner @timer
def func():
time.sleep(1)
print('hahaha')
return 'oh,hsr' ret = func()

5、装饰带参数的函数的装饰器

#要装饰带有参数的函数,只要在内层函数中加上对应的参数就行
def timer(func):
def inner(args):
start = time.time()
func()
end = time.time()
print(args,end-start)
return inner @timer
def func(args):
time.sleep(1)
print('hahaha') func('aaa')

6、固定形式

# 在固定的形式中,我们使用带返回值的,并且不定参数

def wrapper(func):
def inner(*args,**kwargs): #这样就可以接收各种参数
#运行被装饰函数之前要做的事
ret = func(*args,**kwargs)
#运行被装饰函数之后要做的事
return ret
return inner

7、wraps

使用装饰器后,如果我们打印被装饰函数的__name__将会变成装饰器内层函数的名字

@wrapper
def func():
pass print(func.__name__) #打印inner 如果要让它变成的原来的,可以在内层函数的上方加上@wraps(func),需要导入functools模块 from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs): #这样就可以接收各种参数
#运行被装饰函数之前要做的事
ret = func(*args,**kwargs)
#运行被装饰函数之后要做的事
return ret
return inner

8、带参数的装饰器

如果要使用带参数的装饰器,可以在装饰器函数外面再套一层函数,并把要给装饰器的参数给最外层函数
def wrapper(flag):
def wrapper_inner(func):
@wraps(func)
def inner(*args,**kwargs): #这样就可以接收各种参数
#运行被装饰函数之前要做的事
ret = func(*args,**kwargs)
#运行被装饰函数之后要做的事
return ret
return inner @wrapper(FLAG)
def func():
pass

9、多个装饰器装饰一个函数

多个装饰器装饰一个函数的时候,会先从离函数最近的装饰器开始执行

def wrapper1(func):
def inner():
print("---1---")
func()
print("---1---")
return inner def wrapper2(func):
def inner():
print("---2---")
func()
print("---2---")
return inner @wrapper2
@wrapper1
def func():
print("func") func()
#结果
---2---
---1---
func
---1---
---2---

我们来看一下执行顺序

10、原则

开放封闭原则
开放:对扩展是开放的
封闭:对修改时封闭的

最新文章

  1. 创建文本注记TextElement
  2. vim添加未识别文件类型
  3. .net异步编程
  4. Php 输出语句
  5. 关于django Models的个人理解和related_name的使用
  6. GBK转utf-8,宽字符转窄字符
  7. IE6下a标签失效(背景穿透)
  8. TCP协议和UDP协议的区别
  9. Java多线程的几个常用关键字
  10. 基于Xilinx FPGA的视频图像采集系统
  11. 调试 kafka manager 源码
  12. jquery .On()绑定事件的触发机制
  13. Shell函数和数组
  14. Hadoop---桥接集群的搭建
  15. java 正则 贪婪匹配 匹配sql语句中的引号内容
  16. js jquery 函数回调
  17. == equals hashCode 总结比较
  18. Java反射 - 简单的给Bean赋值和取值
  19. IsPostBack用法
  20. 1. Two Sum [Array] [Easy]

热门文章

  1. 为什么使用GitHub
  2. BZOJ 2119 股市的预测 (后缀数组+RMQ)
  3. nginx1.15.8源码安装
  4. unity 显示、隐藏Android导航栏
  5. cogs 466. [NOIP2009] 细胞分裂
  6. echarts 设置x轴的和y轴的属性
  7. 【中山市选2010】【BZOJ2467】生成树
  8. Android Material Design-Getting Started(入门)-(一)
  9. C/C++数据类型的转换之终极无惑
  10. Ubuntu14.04下Mongodb(在线安装方式|apt-get)安装部署步骤(图文详解)(博主推荐)