Python之实战装饰器拆解

实现装饰器需要具备那些知识:

1.函数既”变量” 属于可变化数据

函数是无关顺序的,但是执行调用的函数必须在执行代码前面

示例:

变量:

a=[1,2]  #a为变量名,[1,2]存放内存里面 ==专业称之变量体

函数:

def test1():

   .....

#test1==该函数的名字(如变量名a)

#():内的代码 == [1,2]存放在内存里面 ==专业称之函数体

#注意1:test1获取该函数的内存地址 、test1+ ()==执行该test1函数

#注意2:变量体(函数体)必须最少拥有一个变量名(函数名),否则内存回收

 

 

 

2.高阶函数

a:把一个函数名当做实参传给另外一个函数的函数:

通过实验得到:在不修改被装饰函数源代码的情况下为其添加了功能

b:返回值中包含函数名

通过实验得到:不修改函数的调用方式和源代码也可以添加功能

示例:

import time

def bar():

    time.sleep(3)

    print('in the bar')



def test2(func):

    print(func)

    return func

test2(bar)()

#bar获取的是函数bar函数的内存地址

#bar()才是执行该函数

3.嵌套函数

高阶函数+嵌套函数=装饰器

示例:

import time
def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()#开始时间
        func()#调用开始时间(该装饰我还不清楚,目前这样解释)
        stop_time = time.time()#结束时间
        print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
    return warpper
def test():
    time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
    print('in the test')

a=timmer(test)  # a == warpper
a()             # a()==warpper()

#timmer(test)() == warpper()等于上面两条命令

 

详解:

  1. timmer(test1)得到的是warpper的该函数内存地址
  2. timmer(func)  func=test该函数体
  3. 赋值a  a() ==warpper()
  4. 全局变量和局部变量规则,意味着warpper()可以调用timmer函数的形参func
  5. 最终执行了func()  == test() 

 

timmer函数符合高阶函数,和嵌套函数,所以是装饰器

经过Python优化以后装饰器调用变成如下:

@timmer装饰到指定的函数如def test1()上面:

import time
def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()#开始时间
        func()#调用开始时间(该装饰我还不清楚,目前这样解释)
        stop_time = time.time()#结束时间
        print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
    return warpper


@timmer#调用装饰器,在需要装饰的函数的上方

def test():
    time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
    print('in the test')

test()   

#带装饰器和正常写法的转换:

#func = test

#test = timmer(test)   ==  warpper

#test()=timmer(test)()  ==   warpper()

 

test该函数有形参怎么办?

1.我们知道func = test  

2.timmer(test1)得到的是warpper的该函数内存地址赋值到test

3.test() == warpper() 

4. warpper函数增加参数组(元祖和字典)

5. test(1,2) == warpper(1,2)     warpper函数执行func的时候在把形参给funcOKfun(1,2)

 

示例:

import time
def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()#开始时间
        func(args[0], args[1])#调用开始时间(该装饰我还不清楚,目前这样解释)
        stop_time = time.time()#结束时间
        print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
    return warpper


@timmer#调用装饰器,在需要装饰的函数的上方

def test(a,b):
    time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
    print('in the test')

test(1,2)

#带装饰器和正常写法的转换:

#func = test

#test = timmer(test)   ==  warpper

#test1(1,2)=timmer(test)(1,2)  ==   warpper(1,2)

# func(args[0], args[1]) == test(1,2)

 

test该函数有return怎么办?

示例:

import time
def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()#开始时间
        res = func(args[0], args[1])#调用开始时间(该装饰我还不清楚,目前这样解释)
        stop_time = time.time()#结束时间
        print('the func run time is %s' %(stop_time-start_time))#打印显示xxx开始时间-
        return res
    return warpper

@timmer#调用装饰器,在需要装饰的函数的上方
def test(a,b):
    time.sleep(3)#间隔3秒,也就是被调用了执行到该步骤的时候停3秒,继续往下操作
    return 1
res = test(1,2) 

高阶装饰器(其实都是一样)

猜你喜欢

转载自blog.csdn.net/Burgess_zheng/article/details/85757740