Bootstrap

闭包与装饰器

一、闭包:

1.外部函数嵌套内部函数
2.外部函数将内部函数返回(外部函数返回的是内部函数名)
3.内部函数可以访问外部函数的局部变量(内部函数修改外部函数局部变量用nonlocal)

import random


# 1.外部函数嵌套内部函数
# def fun1():
#     print("fun1")
#     def fun2():
#         print("fun2")
#     fun2()
# fun1()


# 2.外部函数将内部函数返回(外部函数返回的是内部函数名)
def fun1():
    print("fun1")
    def fun2():
        print("fun2")
    return fun2

r = fun1()
r()


#内部函数可以访问外部函数的局部变量
def fun1():
    print(f"fun1")
    datas = []

    def fun2():
        datas.append(random.randint(0, 100))
        print("fun2", datas)

    return fun2


r = fun1()
r()
r()
r()
r()
r()

r1 = fun1()
r1()

print(id(r), id(r1))

二、装饰器:

目的:不改变函数原有实现给函数添加新功能
概念:一个闭包就是一个函数+在创建这个函数时可以访问的变量
实现:闭包 + @语法

三、装饰器案例

1.时间开销

import random
import time

datas = [random.randint(0, 10000) for i in range(10000)]
datas_copy = datas.copy()


def time_cost(f):
    def calc():
        start = time.time()

        f()

        print(f"结束执行: {f.__name__} 消耗时间 {time.time() - start}")

    return calc


@time_cost
def fun1():
    datas.sort()

    print(datas)


# fun1 = time_cost(fun1)

fun1()


# fun1()


@time_cost
def fun2():
    new_datas = sorted(datas_copy)

    print(new_datas)


# fun2 = time_cost(fun2)

fun2()

# fun2()

 

2.权限校验

# 2.编写装饰器添加权限校验
user = None


def login_required(f):
    def check():
        if user:
            f()
        else:
            while True:
                username = input("请输入用户名")
                pwd = input("请输入密码")
                if username == "admin" and pwd == "123456":
                    f()
                    break
                else:
                    print("用户名或密码错误")

    return check


def index():
    print("我是首页")


@login_required
def center():
    print("我是个人中心")


@login_required
def cart():
    print("我是购物车")


index()
center()
cart()

;