zoukankan      html  css  js  c++  java
  • python 闭包函数理解 (顺便回顾一下列表表达是拆分)

    闭包:一个持有外部环境变量的函数就是闭包;闭包是一个能够访问其他函数作用域的函数

    '''
    简化写法
    '''
    def multipliers():
        return [lambda x: i * x for i in range(4)]
    print([m(2) for m in multipliers()])
    
    
    '''
    拆分一下
    '''
    # 拆分 multipliers()第一步:
    def multipliers():
        ls = []                     #列表表达是拆分方法
        for i in range(4):          #lambda x:i*x 调用了上一层函数multipliers()的局部命名空间的变量i
            ret = lambda x: i * x   #这里还可以拆分
            ls.append(ret)
        print(i)  #打印3
        return ls                  #返回的是局部变量,不是闭包
    
    # 拆分 multipliers()第二步:
    def multipliers():
        ls = []                     
        for i in range(4):          
            def inner(x):    #定义 inner函数使用了multipliers()的局部命名空间的变量i
                return x*i      
            ret = inner
            ls.append(ret)
        print(i)  #打印3
        return ls             #返回了函数     
    
    #加一个便于理解的代码
    for i in range(4):
        pass
    print(i)  #打印3
    
    
    ret = []
    for  m in multipliers():
       ret.append(m(2))
    print (ret) # 打印 [6, 6, 6, 6]
    
    print(multipliers()[0](2)) #打印6
    
    '''
    从python解释器开始执行之后,就在内存中开辟了一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。
    但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。
    等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,
    而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
    '''
    '''
    只有当调用闭包函数的时候它才会去引用外层函数的变量,因为在调用闭包函数之前,闭包内部的命名空间还不存在。
    所以multipliers的里面存放了四个函数,当去调用的时候,for i in range(4)这个循环已经执行完毕,此时的i已经是3了,新开辟的命名空间里面的i就是3了
    '''
    
    

    顺便加一个装饰器

    def wrapper(func):
       def inner(request):
           print('start wrapper')
           r = func(request)      #inner函数使用了外部的func参数,所以也是一个闭包
           print('end wrapper')
           return r
        return inner
    
  • 相关阅读:
    Spring之InstantiationAwareBeanPostProcessor接口介绍
    Spring之BeanPostProcessor(后置处理器)介绍
    JVM中垃圾收集算法总结
    JVM中对象的回收过程
    zookeeper实现动态感知服务器上下线
    Spring事务的传播行为
    java工厂模式
    Spring加载流程源码分析03【refresh】
    Redis客户端操作之Jedis
    微服务设计的四个原则
  • 原文地址:https://www.cnblogs.com/amize/p/13267365.html
Copyright © 2011-2022 走看看