• python:闭包,装饰器


    闭包:

    闭包只能存才嵌套函数中
    内层函数对外层还输非全局变量的引用,就会形成闭包
    被引用的非全局标量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系
    自由变量不会在内存中消失

    # __code__.co_freevars : 函数的属性,获取函数中的自由变量
    
    def wrapper():
        l = []    #这个l 是个自由变量,在函数外部是不能改变 l 的值
        def inner(val):
            l.append(val)
            return sum(l)/len(l)
        return inner
    ret = wrapper()
    print(ret.__code__.co_freevars)    # ('l',),可以当做判断一个函数是不是闭包
    
    
    def wrapper(a,b):    # 这里a,b也是自由变量
        def inner():
            res = a+b
            return res
           return inner
    ret = wrapper(2,3)
    print(ret.__code__.co_freevars)    # ('a', 'b')

    装饰器

    装饰器:在不改变 原函数代码 以及 调用方式 的前提下,为其增加新的功能
    import time
    def index():
        time.sleep(2)
        print('welcom login')    # 模拟登陆
    def timmer(f):    # 这里用到了闭包。这里f是个自用变量,自由变量不受函数外部影响
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print(f'测试函数的执行效率{end_time-start_time}')
        return inner
    index = timmer(index)    # 将函数名index作为参数传递给timmer(f),实际上传递的是index指向的内存地址,即 变量f指向了index指向的内存地址。然后将返回值inner重新赋值给index,index指向的内存地址变成了inner()函数的内存地址
    index()
    
    # 语法糖:@,用来当做装饰器装饰函数 ,@timmer()相当于 index = timmer(index)
    import time
    def timmer(f):
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print(f'测试函数的执行效率{end_time-start_time}')
        return inner
    @timmer        # 代码执行到这里的时候,会向下多执行一行
    def index():
        time.sleep(2)
        print('welcome login')
    index()
    
    
    #带参数有返回值的装饰器
    import time
    def timmer(f):
        def inner(*args,**kwargs):
            st = time.time()
            ret = f(*args,**kwargs)
            et = time.time()
            print(f'login application run time{et - st}')
            return ret
        return inner
    @timmer
    def login(name):
        time.sleep(1)
        print(f'welcome to blog,{name}!!')
    login('alex')
    
    
    #标准版的装饰器
    def wrapper(f):
        def inner(*args,**kwargs):
            ''' 添加额外功能,执行被装饰函数之前的操作'''
            ret = f(*args,**kwargs)
            '''添加额外功能,执行被装饰函数之后的操作'''
            return ret
        return inner
    
    
    # 通过改变一个参数,控制代码是否执行
    import time
    def change_start(a):
        def wrapper(f):
            def inner(*args,**kwargs):
                if a:
                    st = time.time()
                    ret = f(*args,**kwargs)
                    et = time.time()
                    ti = et - st
                    return ti
                else:return 'no run'
            return inner
        return wrapper
    @change_start(False)    # 这里传递参数,来控制被装饰函数是否执行
    def login():
        time.sleep(1)
    print(login())
  • 相关阅读:
    springboot配置视图控制器
    springboot测试的方法
    cookie之sameSite
    docker 安装Elasticsearch +kibana
    find + xargs 删除文件名中含有空格的文件
    git,composer 代理
    Composer更新依赖报错Fatal error解决方案
    compose 设置代理 SET HTTP_PROXY="http://192.168.1.103:8080"
    php使用composer常用问题及解决办法集:zlib_decode():data error......
    ERROR: .FileNotFoundError: [Errno 2] No such file or directory: '.\docker-compose.yml:docker-compose.apache.yml'
  • 原文地址:https://www.cnblogs.com/jmuchen/p/13418420.html
Copyright © 2020-2023  润新知