• 函数(闭包函数,装饰器)


    闭包函数

    1.什么是闭包函数。

    定义在函数内部的函数,这个内部函数引用了外部函数变量。

    2.为什么要用闭包函数。

    保存局部信息不被销毁,保证数据的安全性

    3.怎么使用闭包。

    例子:

    # 例一:
    def wrapper():
        a = 1
        def inner():
            print(a)
        return inner
    ret = wrapper()
    ​
    # 例二:
    a = 2
    def wrapper():
        def inner():
            print(a)
        return inner
    ret = wrapper()
    ​
    ​
    # 例三:
    def wrapper(a,b):
        def inner():
            print(a)
            print(b)
        return inner
    a = 2
    b = 3
    ret = wrapper(a,b)

    这三个例子都是闭包函数

    给函数传参数值有两种方式:

      1.普通的传参

    def index1(username):
         print(username)

      2.闭包

    def outter(x,y):
        def my_max():
            if x>y:
                return x
            return y
        return my_max
    res =outter(1,40)
    res1 = outter(10,3)

    4.那么闭包函数可以做哪些事情呢?

      1.可以保存一些非全局变量但不易被销毁,改变的数据

      2.装饰器

    下面我们就引入了装饰器

    装饰器

    1.什么是装饰器。

    就是给被装饰对象加上新的功能。在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。

    2.为什么要使用装饰器。

    这里我们要解释一个新名词,开放封闭原则。

    开放封闭原则:
      开放:对扩展开放
      封闭:对修改封闭

    3.如何使用装饰器

    首先我们按照之前的知识写一下,统计index函数执行的时间

    import time
    def index():
        time.sleep(3)
        print('index.....')
    start = time.time()
    index()
    end = time.time()
    print('index 执行了%s' %(end-start))

    修改一下上面代码,将统计时间用函数包装一下。装饰器简单版本

    import time
    def index():
        time.sleep(3)
        print('index..................')
    
    def outtere(func):
        def get_time():
            start = time.time()
            func()
            end = time.time()
            print('run time:%s',%(end-start))
        return get_time
    index = outter(index)
    index()

    如果我们的Index函数有参数呢,我们可以继续改进一下(无参函数和有参函数都可以直接调用,可以接收任意数量的参数)

    import time
    def index(name):
        time.sleep(3)
        print('%s hello' %name)
    
    def outter(func):
        def get_time(*args,**kwargs):
            start = time.time()
            res = func(*args,**kwargs)
            end = time.time()
            print('run time:%s'%(end-start))
            return res
        return get_time
    
    index = outter(index)
    index('zzp')

    index = outter(index)这句话是不是我们每次在装饰函数时都要这样写?现在有一种很简便的写法

    语法糖在书写的时候应该与被装饰对象紧紧挨着
    两者之间不要有空格

    import time
    
    def outter(func):
        def get_time(*args,**kwargs):
            start = time.time()
            res = func(*args,**kwargs)
            end = time.time()
            print('run time:%s'%(end-start))
            return res
        return get_time
    
    @outter    #index = outter(index)
    def index(name):
        time.sleep(3)
        print('%s hello' %name)
    
    index('zzp')

    装饰器的模板

    def outter(func):
        def inner(*args,**kwargs):
            print('执行被装饰函数之前 你可以做的操作')
            res = func(*args,**kwargs)
            print('执行被装饰函数之后 你可以做的操作')
            return res
        return inner

    带参数的装饰器

    def login_auth2(data_source):
        # data_source = 'file'
        def login_auth(func):
            # func = index
            def inner(*args,**kwargs):  # 这里的参数是跟被装饰函数的参数一一对应
                if user_dic['is_login']:
                    res = func(*args, **kwargs)
                    return res
                else:
                    if data_source == 'file':
                        username = input('please input your username>>>:').strip()
                        password = input('please input your password>>>:').strip()
                        if username == 'jason' and password == '123':
                            user_dic['is_login'] = True
                            res = func(*args,**kwargs)
                            return res
                        else:
                            print('username or password error')
                    elif data_source == 'MySQL':
                        print('from MySQL')
                    elif data_source == 'ldap':
                        print('ldap')
                    else:
                        print('暂无该数据来源')
            return inner
        return login_auth
    @login_auth2('file')
    def index():
      print('.....')
    index()

    这里的@login_auth2('file') 相当于  index = login_auth(index) 

    叠加多个装饰器(**)

      1.加载顺序(outter函数的调用顺序)自下而上

      2.执行顺序(wrapper函数的执行顺序)自上而下

    def outter1(func1): #func1=wrapper2的内存地址
        print('加载了outter1')
        def wrapper1(*args,**kwargs):
            print('执行了wrapper1')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    
    def outter2(func2): #func2=wrapper3的内存地址
        print('加载了outter2')
        def wrapper2(*args,**kwargs):
            print('执行了wrapper2')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    
    def outter3(func3): # func3=最原始的那个index的内存地址
        print('加载了outter3')
        def wrapper3(*args,**kwargs):
            print('执行了wrapper3')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    
    @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
    @outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
    @outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
    def index():
        print('from index')
    
    index()
    万般皆下品,唯有读书高!
  • 相关阅读:
    学习 Message(18): WM_SYSCOMMAND 消息[二] : LParam 参数
    学习 Message(20): WM_SYSCOMMAND 消息[四] : 使最大最小化按钮失效
    学习 Message(16): 测试 $0118 号消息
    学习 Message(15): 让窗体同时响应键盘事件的方法
    学习 Message(17): WM_SYSCOMMAND 消息[一]
    请教大家, 关于 $0118 号消息
    学习 Message(21): WM_SYSCOMMAND 消息[五] : 点击关闭按钮让窗体最小化
    学习 Message(22): WM_SYSCOMMAND 消息[六] : 系统菜单综合操作示例
    根据颜色值获取颜色常量名: ColorToIdent
    “博客无双”第二期拍卖活动将于2011年1月26日14:00开始
  • 原文地址:https://www.cnblogs.com/s686zhou/p/11170560.html
Copyright © 2020-2023  润新知