闭包和装饰器

一:闭包的理解:

闭包就是内层函数对外层函数变量的引用

实例:

# 闭包
def func():
    a = 12
    def inner():
        print("a>>", a)
    return inner
func()()

二:装饰器的理解:

在不改变原函数的情况下,给这个函数增加额外的功能(登陆验证和打印日志等会用到)

简单理解版的装饰器:

# 需求测试test的运行时间
import time
def test():
    a=1+34
    print("a值为〉〉",a)


def func(f):
    def inner():
        start_time=time.time()
        time.sleep(1)
        f()
        end_time=time.time()
        print("执行时间",end_time-start_time)
    return inner

test=func(test)  # inner
test()  # inner()
'''
流程分析:
第一步:执行 func(test),将test参数传入给f,这个时候,内层的inner没有执行,func()函数执行,直接返回inner,inner返回给test,
因为test=func(test),所以,inner直接返回给左边的test,此时,test就是inner
第二步:执行test(),其实就是执行inner(),即执行内部函数def inner().
第三步:执行到f()时候,由于之前已经将test 参数传入到func函数里面的f,所以,现在执行f()--->test(),完成对目标函数的测试效果。
'''

语法糖 @ 版本装饰器

import time
def func(f):
    def inner():
        start_time=time.time()
        time.sleep(1)
        f()
        end_time=time.time()
        print("执行时间",end_time-start_time)
    return inner

# 需求测试test的运行时间

@func   # 此时,@func就相当于 test=func(test),@ 就是语法糖
def test():
    a=1+34
    print("a值为〉〉",a)

@func
def test02():
    c="qeq"
    d="gdfa"
    print("c+d>>",c+d)

# test=func(test)  # inner
test()  # inner()
test02()  # inner()

三:被装饰的函数带参数的装饰器

主要要理解,*args和**kwargs是什么

# *args的理解,在给函数传参的时候,* 代表聚合,将传入的参数进行打包
# 打包成一个元组
def func01(*args):
    print("args=", args)

func01(1, 2, 3)  # args= (1, 2, 3)

**kwargs 则传入关键字参数的时候用的到

被装饰的函数带参数:

import time
def func(f):
    # ** kwargs 则是在传递关键字参数的时候才用的,且必须要要用到
    def inner(*args,**kwargs):  #  此时的*args 中的 * 代表聚合,将输入的实参进行打包成一个元组
        print("1>>",args) # (10, 18)
        start_time=time.time()
        f(*args,**kwargs)  # 此时的*args 中的 * 代表打散,将传过来的元组进行打散, 比如   10 18 
        # 打成一个个的参数 10 18,然后逐一分给函数f的参数中
        print(">>",*args)  # 10 18
        end_time=time.time()
        print("执行时间",end_time-start_time)
    return inner


# 需求测试test的运行时间

@func   # 此时,@func就相当于 test=func(test),@ 就是语法糖
def test(x,y,a):
    time.sleep(1)
    print("a值为〉〉",x+y,a) #  28  a是关键字参数

@func
def test02(x,y,z):
    time.sleep(0.2)
    print("test02的值是:",x+y+z)


test(10,18,a="a是关键字参数")  # inner()
# test02(1,2,1)

被装饰的函数带返回值:

import time


def timer(f):
    def inner(*args, **kwargs):
        start_time = time.time()

        # f(*args,**kwargs)
        ret = f(*args, **kwargs)  #第二步: ret 得到的时func函数执行的返回结果,
        print(ret)

        end_time = time.time()
        print("执行时间〉〉", end_time - start_time)
        return ret  #  第三步: 将被装饰的函数的返回值返回给inner

    return inner

@timer  # func=timer(func)
def func(x, y):
    time.sleep(0.1)
    return x + y

ret1 = func(1, 2)  #第一步: func(1,2)函数执行的时候,func的返回值返回给func,
print("ret=", ret1)  # 3   第四步: 得到inner的返回值 ,其实就是被装饰的函数的返回值
原文地址:https://www.cnblogs.com/one-tom/p/11263178.html