• python 进阶之路:绑定延迟


    看看下面一题,试着写出自己的答案。
    def multipliers():
        return [lambda x: i * x for i in range(4)]
    
    
    print([m(2) for m in multipliers()])
    print(type(multipliers()))
    
    
    res:
    
    [6, 6, 6, 6]
    <class 'list'>
    
    输出结果不是我们想的[0,2,4,6],这是为什么呢?如何输出我们想的结果呢?
    
    首先,上述问题产生的原因是python 闭包的延迟绑定。在这里你可能会有疑问
    ,什么是闭包?
    在python 的核心编程里,闭包定义如下:
    如果在一个内部函数里,对外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被
    认定为闭包。
    总结为三点:
    1、是一个内嵌函数
    2、对外部函数变量的引用
    3、外部函数返回内嵌函数
    简单的闭包eg:
    def counter(start_at=0):
        count = [start_at]
        def incr():
            count[0] += 1
            return count[0]
        return incr
    
    继续刚才的问题,python 闭包的延迟绑定,意味着
    内部函数被调用,时,参数的值在闭包内进行查找。因此,
    当任何有multipliers()返回的函数被调用时,i 的值
    将在附近范围进行查找。那是不管返回函数是否被调用,for
    循环已经完成,i被赋予最终值3,因此,每次返回的函数乘以
    传递过来的值3 ,因为上段代码传过来的值是2,他们最终的返回都是6。
    
    
    以匿名函数的形式,看着你可能存在疑惑,现在为你转换成 for循环语句,
    便于你理解。
    
    def func():
        fun_list = []
        for i in range(4):
            def foo(x):
                return x*i
            fun_list.append(foo)
        return fun_list
    for m in func():
      print m(2)
    
    
    
    
    那现在考虑一下,如何输出我们想的结果【0,2,4,6】?
    两种方法为您推荐:
    方法一:
    def multipliers():
        for i in range(4): yield lambda x: i * x
    print([m(2) for m in multipliers()])
    print(type(multipliers()))
    
    res:
        [0, 2, 4, 6]
        <class 'generator'>
    
    方法二:
    
    def multipliers():
        return [lambda x, i=i: i * x for i in range(4)]
    
    
    print([m(2) for m in multipliers()])
    print(type(multipliers()))
    
    
    res:
    
        [0, 2, 4, 6]
        <class 'list'>
  • 相关阅读:
    vue-cli项目npm run build后,index.html无法在浏览器打开
    前端工具
    关于 IIS 中 iconfont.woff 报 404(Not Found) 的原因即解决方法
    表格行上下移动、置顶的Javascript代码
    纯js国际化(使用技术:i18n)
    【整理】前端国际化小结
    js比较两个数字的大小不能直接比
    input事件中文触发多次问题研究
    linux(centos8):使用tree命令查看目录结构
    nginx安全:配置网站图片防盗链
  • 原文地址:https://www.cnblogs.com/liangliangzz/p/14307045.html
Copyright © 2020-2023  润新知