ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python 进阶之路:绑定延迟

2021-01-21 11:35:44  阅读:181  来源: 互联网

标签:闭包 return 进阶 python 绑定 multipliers print def 函数


看看下面一题,试着写出自己的答案。
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'>

 

标签:闭包,return,进阶,python,绑定,multipliers,print,def,函数
来源: https://www.cnblogs.com/liangliangzz/p/14307045.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有