python之路 装饰器

为什么要用装饰器??????????
装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器返回值意识一个函数对象。它有需求的场景,比如:插入日志,
性能测试,事务处理,缓存,权限校检等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续使用。概括的
讲,装饰器的作用就是为已经存在的对象添加额外的功能。


装饰器的形成过程

import time

def func1():
    print('in func1')

def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

func1 = timer(func1)
func1()

装饰器——简单版1
一个简单的装饰器
import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> func1 = timer(func1)
def func1():
    print('in func1')


func1()

装饰器——语法糖
语法糖简化

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

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

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

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

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

装饰器——带参数的装饰器
带参数的装饰器
import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print('in func1')

@timer   #==> func1 = timer(func1)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))
动态传参装饰器
import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))

装饰器——带返回值的装饰器
带返回值的装饰器

 

开放封闭原则

  1.对扩展是开放的

            程序是徐亚不断更新和添加不同功能的

  2.对修改是封闭的

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

 

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

装饰器的主要功能:

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

def timer(func):
    def inner(*args,**kwargs):
        '''执行函数之前要做的'''
        re = func(*args,**kwargs)
        '''执行函数之后要做的'''
        return re
    return inner
装饰器的固定格式

 

带参数的装饰器格式

def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print('''执行函数之前要做的''')
            re = func(*args,**kwargs)
            if flag:
                print('''执行函数之后要做的''')
            return re
        return inner
    return timer

@outer(False)
def func():
    print(111)

func()
带参数的装饰器

 

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

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()
多个装饰器装饰同一个函数

 

注意:

深度理解好闭包函数的本质能更好的理解装饰器

 

装饰器的一个小应用

1.统计当前程序中有多少个函数被装饰了

2.统计本次程序执行有多少个带这个装饰器的函数被调用了

l = []
def wrapper(func):
    l.append(func)  #统计当前程序中有多少个函数被装饰了
    def inner(*args,**kwargs):
        # l.append(func)  #统计本次程序执行有多少个带这个装饰器的函数被调用了
        ret = func(*args,**kwargs)
        return ret
    return inner

@wrapper  #f1 = wrapper(f1)
def f1():
    print('in f1')

@wrapper #f2 = wrapper(f2)      f2= func   f2 =inner
def f2():
    print('in f2')

@wrapper #f2 = wrapper(f2)
def f3():
    print('in f3')
f2()



print(l)
View Code

 

posted @ 2017-08-02 15:47  Style_S  阅读(70)  评论(0)    收藏  举报