再学装饰器

装饰器

实现装饰器的知识储备

1.函数即“变量”

2.高阶函数

  a.把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

  b.返回值中包含函数名(不修改函数的调用方式)

3.嵌套函数

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

 

1.函数即变量:

图一中x,y,test,calc都是变量,同样图二中的foo和bar函数名也是变量。

 

2.高阶函数

  代码解析:

def bar():
    print('in the bar')
def test(func):
    print(func)
test(bar)
把bar当做变量传给test函数当做参数,此时print(func)就是bar的地址,func()就是调用bar()函数

  下一步思路:

def bar():
    time.sleep(3)
    print('in the bar')

def test(func):
    start_time = time.time()
    func()  # run bar()
    stop_time = time.time()
    print('the func run time is %s' % (stop_time - start_time))

test(bar)
不是装饰器,虽然没有修改源代码,但是调用方式变了,本来是bar(),现在是test(bar)

  接下来思路:

import time

def bar():
    time.sleep(3)
    print('in the bar')

def test(func):
    print(func)
    return func

print(test(bar))  # test(bar)就是传进去bar函数的地址
结果:
<function bar at 0x000002142A5A1E18>
<function bar at 0x000002142A5A1E18>
import time

def bar():
    time.sleep(3)
    print('in the bar')

def test(func):
    print(func)
    return func

bar = test(bar)  # 把地址重新赋值给bar变量
bar()  # 此时执行bar函数 

3.嵌套函数:

引入:局部作用域和全局作用域的访问顺序  

x = 0
def grandpa():
    x = 1
    def dad():
        x = 2
        def son():
            x = 3
            print(x)
        son()
    dad()
grandpa()
局部作用域和全局作用域举例
def foo():
    print('in the foo')
    def bar():
        print('in the bar')
    bar()
foo()

 

4.开始写装饰器

装饰器的原则是:开放对扩展(增加新功能)、封闭修改源代码(不改变源代码)、不改变调用方式(原函数是怎么调用的现在还是怎么调用)。

  4.1使用高阶函数尝试给原函数增加功能。

import time
def test1():
    time.sleep(1)
    print('in the test1')
def test2():
    time.sleep(2)
    print('in the test2')
def deco(func):
    start_time = time.time()
    return func
    stop_time = time.time()
    print('in func run time is %s'%(stop_time-start_time))
test1 = deco(test1)
test1()
test2 = deco(test2)
test2()
利用高阶函数实现了上面的思路,不改变原函数的调用方式,不过没有加功能

  4.2利用嵌套函数

def timer():
    def deco():
        pass

  4.3嵌套函数往上面没加功能里面套形成装饰器

import time
def test1():
    time.sleep(1)
    print('in the test1')
def test2():
    time.sleep(2)
    print('in the test2')
def timer(func):  # timer(test1)  func = test1
    def deco():
        start_time = time.time()
        func()  # run test1
        stop_time = time.time()
        print('in func run time is %s' % (stop_time - start_time))
    return deco
test1 = timer(test1)
test1()  # -->deco
test2 = timer(test2)
test2()

  4.4最终的装饰器(语法糖引入)

import time


def timer(func):
    def deco():
        start_time = time.time()
        func()
        stop_time = time.time()
        print('in func run time is %s' % (stop_time - start_time))

    return deco


@timer
def test1():
    time.sleep(1)
    print('in the tset1')


@timer
def test2():
    time.sleep(2)
    print('in the test2')


test1()
test2()

 

posted @ 2019-04-21 13:51  blog_wu  阅读(123)  评论(0编辑  收藏  举报