闭包函数与装饰器

98 阅读2分钟

闭包函数

定义:
1.定义在函数内部的函数
2.内部函数使用了外部函数的名称空间中的名字
"闭"代表函数是内部的,"包"代表函数外’包裹’着对外层作用域的引用。因而无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量。
3.目前为止,我们得到了两种为函数体传值的方式,一种是直接将值以参数的形式传入,另外一种就是将值包给函数

def outer(username):
    def index():
        print(username)
    return index

res = outer('jason')
res()
4.作用:提供了第二种给函数传值的方式

装饰器简介

1.定义:在不改变装饰对象内部代码和调用方式的情况下为该函数添加新的功能
2.原则:对修改关闭,对扩展开放

装饰器模板


def outer(func_name):
   
    def inner(*args, **kwargs):
        print('执行被装饰对象之前进行的操作')
        rfunc_name(*args, **kwargs)
        print('执行被装饰对象之后进行的操作')
        return res
    return inner
@outer
home = outer(home)
home()
语法糖:在被装饰函数前加 '@outer'
# 装饰器语法糖
    import time

    @outer  #  home = outer(真正的函数名home)
    def home():
        '''我是home函数 我要热死了!!!'''
        time.sleep(1)
        print('from home')
        return 'home返回值'

    # help(home)
    # print(home)
    home()

    # def index():
    #     '我是index函数 我的功能很强大'
    #     pass
    #
    # help(index)

多层装饰器

def outter1(func1):
    print('加载了outter1')
    def wrapper1(*args, **kwargs):
        print('执行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

def outter2(func2):
    print('加载了outter2')
    def wrapper2(*args, **kwargs):
        print('执行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):
    print('加载了outter3')
    def wrapper3(*args, **kwargs):
        print('执行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3

c3572aa79686b8cbc615f11b0edf4d1.png

有参装饰器

def login_auth(func_name):
    def inner(*args, **kwargs):
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        if username == 'jason' and password == '123':
            res = func_name(*args, **kwargs)
            return res
        else:
            print('用户权限不够 无法调用函数')
    return inner

"""
需求:在装饰器内部可以切换多种数据来源
	列表
	字典
	文件
"""
def outer(condition,type_user):
    def login_auth(func_name):  # 这里不能再填写其他形参
        def inner(*args, **kwargs):  # 这里不能再填写非被装饰对象所需的参数
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            # 应该根据用户的需求执行不同的代码
            if type_user =='jason':print('VIP')
            if condition == '列表':
                print('使用列表作为数据来源 比对用户数据')
            elif condition == '字典':
                print('使用字典作为数据来源 比对用户数据')
            elif condition == '文件':
                print('使用文件作为数据来源 比对用户数据')
            else:
                print('去你妹的 我目前只有上面几种方式')
        return inner
    return login_auth
@outer('文件','jason')
def index():
    print('from index')
index()

9ec10e3fa1e2828941a82ef8c19263e.png