zoukankan      html  css  js  c++  java
  • 2019-07-11 闭包函数和装饰器

    一、闭包函数

      定义:定义在内部的函数引用外部函数的名字(变量)叫做闭包函数

      要打印的是inner函数的x,因为这个函数里面没有定义x的值,所以找上一层的局部变量x = 111。执行代码,outter函数被调用,返回值为inner,用变量res接收,所以res = inner,下面再用res(),就是inner(),调用inner函数,执行里面代码,打印结果为111

    def outter():
        x = 111
        def inner():
            print(x)
        return inner
    res = outter()  # res就是inner函数内存地址
    res()    #111

      给函数体传值的两种方式:

        1.函数调用时候直接传参

    def index1(username):
        print(username)
    res = index1('aa')      #aa

        2.闭包传参

      这个和刚开始定义的闭包函数一样只不过是把变量x,y放在outter函数里面当形参,在调用的时候传实参

    def outter(x,y):
        # x = 1
        # y = 40
        def my_max():
            if x > y:
                return x
            return y
        return my_max
    res1 = outter(1,40)  # res就是my_max函数的内存地址
    print(res1())    #40

    二、装饰器

      定义:给被装饰的对象添加新的功能的一个工具。  目的:更方便的使用新添加的新功能

      装饰器(可调用对象)必须遵守的两个原则:

        1.不可改变被装饰对象的代码

        2.不可改变 被装饰对象的调用方式(假如调用方式是idnex(),使用装饰器之后也是这种调用方式)

      

      简单版本:

      在原始函数index函数上加一个时间计算功能,最后也是调用了index(),没有违反装饰器的两个原则。运行函数先到outter调用,里面传一个参数index(这个是最原始的index函数的内存地址),然后返回get_time,用变量index接收。index()其实就是调用get_time函数。执行里面代码,func()就是之前传的func参数,index()调用。

    import time
    def index():
        time.sleep(3)
        print('睡醒了')
    
    def outter(func):  # func = 最原始的index函数的内存地址
        def get_time():
            start = time.time()
            func()  # func = index函数的内存地址() 直接调用
            end = time.time()
            print('index run time:%s'%(end-start))
        return get_time
    index = outter(index)  # outter(最原始的index函数内存地址)
    # index指向get_time函数的内存地址
    index()   #睡醒了

      升级版本:(被装饰的函数需要参数,之前的用法需要在get_time里面的func()写参数,才能使用正确。统一参数写法:*args,**kwargs)

    import time
    def index():
        time.sleep(3)
        print('澳门最大线上赌场开业啦 性感tank在线发牌!')
        return 'index'
    # res1 = index()
    
    def login(name):
        time.sleep(1)
        print('%s is sb'%name)
        return 'login'
    # res = login('egon')
    
    def outter(func):  # func = 最原始的login函数的内存地址
        def get_time(*args, **kwargs):  # args = ('egon',) kwargs = {}
            start = time.time()
            res = func(*args, **kwargs)  # 最原始的login函数的内存地址() 直接调用  func('egon')
            end = time.time()
            print('func run time:%s'%(end-start))
            return res
        return get_time
    login = outter(login)  # outter(最原始的login函数的内存地址)
    res = login('egon')
    print(res)
    index = outter(index)
    res1 = index()
    print(res1)
    代码

      这样设置之后可以接受任意参数的函数。

     三、装饰器语法糖

      语法糖在书写的时候应该与被装饰器紧紧挨着,两者之间不要有空。把装饰器赋值给紧挨这的的可调用对象,并且把紧挨着的函数名当做参数传递到装饰器中

    四、多个装饰器一起使用

       注意:装饰器装饰顺序:从下往上

            装饰器执行效率:从上往下

     

  • 相关阅读:
    维护
    zabbix监控线
    java——快排、冒泡、希尔、归并
    java——注解处理器
    spring boot——常用注解
    java——修改txt文件中某一行的内容
    spring boot——关于一个Mysql主键的问题
    mysql
    springboot
    自信点,不要怕
  • 原文地址:https://www.cnblogs.com/wangcuican/p/11172978.html
Copyright © 2011-2022 走看看