装饰器

讲装饰器前首先要理解闭包的概念,我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,一起构成闭包。

下面用伪代码进行闭包格式的描述

def 外层函数(参数):
    def 内层函数():
        print("内层函数执行", 参数)

    return 内层函数

内层函数的引用 = 外层函数("传入参数")
内层函数的引用()

外层函数中的参数,不一定要有,据情况而定,但是一般情况下都会有并且在内函数中使用到。

def func(a, b):
    def line(x):
        return a * x - b

    return line

line = func(2, 3)
print(line(5))

结果得到 7
在这个案例中,外函数func有接收参数 a=2,b=3,内函数line接收参数x=5,在内函数体中计算了a*x-b 即 2×5-3的值作为返回值,外函数返回内函数的引用,这里的引用指的是内函数line在内存中的起始地址,最终调用内函数line()得到返回值7

内函数中修改外函数的值

一般在函数结束时,会释放临时变量,但在闭包中,由于外函数的临时变量在内函数中用到,此时外函数会把临时变量与内函数绑定到一起,这样虽然外函数结束了,但调用内函数时依旧能够使用临时变量,即闭包外层的参数可以在内存中进行保留
如果想要在内函数中修改外函数的值,需要使用 nonlocal 关键字声明变量

def func(a, b):
    def line(x):
        nonlocal a
        a = 3
        return a * x - b

    return line


line = func(2, 3)
print(line(5))

答案是12

装饰器

一个装饰器最常见的例子:

 

def set_func(func):
    def call_func():
        print("--权限1--")
        print("--权限2--")
        func()
    return call_func
@set_func  #@set_func 等价于test1=set_func(test1)
def test1():
    print("李玲玲")
# test1=set_func(test1)
test1()

 

@是python的语法糖

 

 扩展一、对有参数无返回值的函数进行装饰

def set_func(func):
    def call_func(a):
        print("--权限1--")
        print("--权限2--")
        func(a)
    return call_func
@set_func  #@set_func 等价于test1=set_func(test1)
def test1(num):
    print("李玲玲%d"%num)
# test1=set_func(test1)
test1(100)

扩展二、对不定长的参数的函数进行装饰

def set_func(func):
    def call_func(*args,**kwargs):
        print("--权限1--")
        print("--权限2--")
        func(*args,**kwargs)
    return call_func
@set_func  #@set_func 等价于test1=set_func(test1)
def test1(num,*args,**kwargs):
    print("---test---%d"%num)
    print("---test---" , args)
    print("---test---" , kwargs)
# test1=set_func(test1)
test1(100)
test1(100,200)
test1(100,200,300,mm=100)

扩展三、对带有返回值的函数进行修饰

def set_func(func):
    def call_func(*args,**kwargs):
        print("--权限1--")
        print("--权限2--")
        return func(*args,**kwargs)
    return call_func
@set_func  #@set_func 等价于test1=set_func(test1)
def test1(num,*args,**kwargs):
    print("---test---%d"%num)
    print("---test---" , args)
    print("---test---" , kwargs)
    return 'ok'
# test1=set_func(test1)
print(test1(100))

 

posted @ 2020-09-22 20:47  小龙虾爱大龙虾  阅读(112)  评论(0)    收藏  举报