zoukankan      html  css  js  c++  java
  • 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())
  • 相关阅读:
    拉格朗日插值
    [数论] hdu 5974 A Simple Math Problem (数论gcd)
    混合图欧拉回路
    上下界网络流
    HDU 6623 Minimal Power of Prime(数学)
    图的连通度
    最小点权覆盖和最大点权独立集
    最大权闭合子图(最小割,蕴含式最大获利问题)
    CodeForces Goodbye 2017
    网络流建模汇总
  • 原文地址:https://www.cnblogs.com/jmuchen/p/13418420.html
Copyright © 2011-2022 走看看