专栏首页python3Python全栈开发之---装饰器

Python全栈开发之---装饰器

1、装饰器的形成过程

 1 import time
 2 
 3 def func1():
 4     print('in func1')
 5 
 6 def timer(func):
 7     def inner():
 8         start = time.time()
 9         func()
10         print(time.time() - start)
11     return inner
12 
13 func1 = timer(func1)
14 func1()

碍眼的那句话就是还要在做一次赋值调用。。。

你觉得碍眼,python的开发者也觉得碍眼,所以就为我们提供了一句语法糖来解决这个问题!

 1 import time
 2 def timer(func):
 3     def inner():
 4         start = time.time()
 5         func()
 6         print(time.time() - start)
 7     return inner
 8 
 9 @timer   #==> func1 = timer(func1)
10 def func1():
11     print('in func1')
12 
13 
14 func1()
15 
16 装饰器——语法糖

到这里,我们可以简单的总结一下:

  装饰器的本质:一个闭包函数

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

还有一个问题要解决,刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?

 1 import time
 2 def timer(func):
 3     def inner(*args,**kwargs):
 4         start = time.time()
 5         re = func(*args,**kwargs)
 6         print(time.time() - start)
 7         return re
 8     return inner
 9 
10 @timer   #==> func1 = timer(func1)
11 def func1(a,b):
12     print('in func1')
13 
14 @timer   #==> func2 = timer(func2)
15 def func2(a):
16     print('in func2 and get a:%s'%(a))
17     return 'fun2 over'
18 
19 func1('aaaaaa','bbbbbb')
20 print(func2('aaaaaa'))
21 
22 装饰器——成功hold住所有函数传参

我们还要在装饰器上加上一点来完善它:

 1 from functools import wraps
 2 
 3 def deco(func):
 4     @wraps(func) #加在最内层函数正上方
 5     def wrapper(*args,**kwargs):
 6         return func(*args,**kwargs)
 7     return wrapper
 8 
 9 @deco
10 def index():
11     '''哈哈哈哈'''
12     print('from index')
13 
14 print(index.__doc__)
15 print(index.__name__)
16 
17 装饰器——wraps demo

2、开放封闭原则

  1.对扩展是开放的

    为什么要对扩展开放呢?

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

  2.对修改是封闭的

    为什么要对修改封闭呢?

    就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

装饰器完美的遵循了这个开放封闭原则。

3、装饰器的主要功能和装饰器的固定结构

装饰器的主要功能:

在不改变函数调用方式的基础上在函数的前、后添加功能。

装饰器的固定格式:

 1 def timer(func):
 2     def inner(*args,**kwargs):
 3         '''执行函数之前要做的'''
 4         re = func(*args,**kwargs)
 5         '''执行函数之后要做的'''
 6         return re
 7     return inner
 8 
 9 装饰器的固定格式
10 
11 from functools import wraps
12 
13 def deco(func):
14     @wraps(func) #加在最内层函数正上方
15     def wrapper(*args,**kwargs):
16         return func(*args,**kwargs)
17     return wrapper
18 
19 装饰器的固定格式——wraps版

4、带参数的装饰器

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

一个一个的取消掉? 没日没夜忙活3天。。。

过两天你领导想通了,再让你加上。。。

 1 def outer(flag):
 2     def timer(func):
 3         def inner(*args,**kwargs):
 4             if flag:
 5                 print('''执行函数之前要做的''')
 6             re = func(*args,**kwargs)
 7             if flag:
 8                 print('''执行函数之后要做的''')
 9             return re
10         return inner
11     return timer
12 
13 @outer(False)
14 def func():
15     print(111)
16 
17 func()
18 
19 带参数的装饰器

5、多个装饰器装饰同一个函数

有些时候,我们也会用到多个装饰器装饰同一个函数的情况。

 1 def wrapper1(func):
 2     def inner():
 3         print('wrapper1 ,before func')
 4         func()
 5         print('wrapper1 ,after func')
 6     return inner
 7 
 8 def wrapper2(func):
 9     def inner():
10         print('wrapper2 ,before func')
11         func()
12         print('wrapper2 ,after func')
13     return inner
14 
15 @wrapper2
16 @wrapper1
17 def f():
18     print('in f')
19 
20 f()
21 
22 多个装饰器装饰同一个函数

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 装饰器和推导式

    py3study
  • Python 函数作为参数传递

    #map()的功能是将函数对象依次作用于表的每一个元素,每次作用的结...

    py3study
  • Python函数式编程之装饰器

    py3study
  • 装饰器和推导式

    py3study
  • Python 函数作为参数传递

    #map()的功能是将函数对象依次作用于表的每一个元素,每次作用的结...

    py3study
  • Python之函数的进阶(带参数的装饰器)

    函数篇--装饰器二 带参数的装饰器 def outer(flag): def timer(func): def inner(*args,...

    新人小试
  • Python类中的装饰器在当前类中的声明与调用详解

    有时,比如写RF的测试库的时候,很多方法都写在一个类里。我们又可能需要一个通用的装饰器,比如,要给某个底层类的方法打桩,查看入参和出参,用以理解业务;或者要ho...

    砸漏
  • python 高阶函数:Decorato

    print log('execute') print log(now) print log('execute')(now)

    py3study
  • go设计模式之抽象工厂

    在上一篇文章中,通过手机的例子对工厂方法进行了展开。制造商不单单只生产手机这一种产品,同时也生产pc,如果工厂扩展其它业务,工厂方法模式就不适用了。为了实现工厂...

    暮雨
  • Docker-compose 安装与基本使用(四)

    Compose有多种安装方式,例如通过 shell, pip以及将 Compose作为容器安装等。本次安装以Shell 为主。

    Jacob丶

扫码关注云+社区

领取腾讯云代金券