十二天:闭包和装饰器

闭包函数

什么是闭包函数

在一个内嵌函数中,对在外部的函数变量的引用,那么着个内嵌函数就被成为闭包函数

定义在外部函数但由内部函数引用的变量被称为自由变量

闭包函数至少是个函数嵌套

def f1(x):
    def f2():
        print(x)
    return f2
num = f1(2)
num()
def outer(x,y):
    def inner():
         nonlocal x ,y
         x += 1
         y += 2
         print(f'x:{x},y:{y}')
    return inner
test = outer(2,5)
test()
test()

使用闭包函数去掉了全局变量的使用,而且将inner函数封装在了outer函数中,使外部不可调用。

当函数outer运行完成后,它的参数x,y依然存在,因为他们被闭包了,所以不会被回收。

装饰器

装饰器相当于闭包函数的高级应用,闭包函数传的参数是变量,而装饰器传的参数是一个函数。装饰器是用来不修改源码和调用方式来给原函数增加功能的。

  1. 装饰器本身是函数,只不过它用来装饰 被装饰的函数
  2. 装饰器装饰函数 不改变被装饰函数源代码
  3. 装饰器装饰函数 不改变被装饰函数的调用方式
import time


def index():
    """被装饰的函数"""
    print('index')
    time.sleep(1)


# time_count装饰器:对被装饰函数计时
def time_count(func):  # func才是真正的index
    """装饰器"""

    def wrapper():
        start = time.time()
        func()
        end = time.time()
        print(end - start)

    return wrapper


index = time_count(index)  # index == wrapper
index()  # wrapper()

带返回值的装饰器

import time


def index():
    """被装饰的函数"""
    print('x',x)
    print('index')
    time.sleep(1)

    return 'index'


# time_count装饰器:对被装饰函数计时
def time_count(func):  # func才是真正的index
    """装饰器"""
    def wrapper():
        start = time.time()
        res = func()  # index()
        end = time.time()
        print(end - start)
        return res

    return wrapper


index = time_count(index)  # index == wrapper
res = index()  # wrapper()
print(res)

对于有返回值的函数,我们可以拿一个变量名去接收这个返回值

res = func() 然后return res

有参数的装饰器

import time


def index(x,y,z=10):
    """被装饰的函数"""
    print('x',x)
    print('index')
    time.sleep(1)

    return 'index'


# time_count装饰器:对被装饰函数计时
def time_count(func):  # func才是真正的index
    """装饰器"""

    def wrapper(*args,**kwargs):  # (10, 20)  # *args和**kwargs接收了所有的参数
        start = time.time()
        res = func(*args,**kwargs)  # index()  # *(10,20)  # *args和**kwargs打散参数传给真正的index
        end = time.time()
        print(end - start)

        return res

    return wrapper


index = time_count(index)  # index == wrapper
res = index(10,20,320)  # wrapper()
print(res)

假如我们不知道原函数有多少参数,我们就可以在装饰器中使用可变长参数

def wrapper(*args,**kwargs):

res = func(*args,**kwargs)

最后使用时再传值进去

装饰器语法糖

@装饰器的函数名

index = time_count(index) == @time_count

装饰器函数要写在被装饰函数的上面,@下面写被装饰函数。

装饰器模板

综上,我们就可以得到一个装饰器的模板,使用时直接套用就好了

def deco(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        pass
        return res
    return wrapper

    @decp
    def show(name, age):
        print(name,age)

    show('ly',10)

猜你喜欢

转载自www.cnblogs.com/lyyblog0715/p/11574951.html