美文网首页
python陷阱(一):两道关于闭包的题

python陷阱(一):两道关于闭包的题

作者: warmsirius | 来源:发表于2019-08-22 11:45 被阅读0次

两道题目

  • 题目1
def multipiers1():
    return [lambda x: i*x for i in range(4)]
  • 题目2
def multipiers2():
    return (lambda x: i*x for i in range(4))

输出

  • 题目1
print([m(2) for m in multipiers1()])

# [6, 6, 6, 6]
  • 题目2
print([m(2) for m in multipiers2()])

# [0, 2, 4, 6]

带你探究为什么?

问题1:题目1和题目2函数返回分别是什么?

print(multipiers1())

# 输出
[<function multipiers1.<locals>.<listcomp>.<lambda> at 0x111bac400>, <function multipiers1.<locals>.<listcomp>.<lambda> at 0x111bac598>, <function multipiers1.<locals>.<listcomp>.<lambda> at 0x111bac488>, <function multipiers1.<locals>.<listcomp>.<lambda> at 0x111bac510>]


print(multipiers2())

# 输出
<generator object multipiers2.<locals>.<genexpr> at 0x1119926d0>

由上面可以看出,函数1返回的是四个函数的列表,函数2返回的是一个生成器。
其实懂点python基础的都知道,题目1返回的是列表生成式,当然列表生成式里面的元素就是lambda函数自身啦,题目2返回的生成器表达式,当然返回的就是生成器啦~

问题2:为什么题目1返回的是[6, 6, 6, 6]?

题目1产生的原因是:

Python 闭包的延迟绑定:这意味着内部函数被调用时,参数的值在闭包内
进行查找。因此,当任何由multipliers()返回的函数被调用时,i 的值将在附近的范围进行查找。那时,不管返回的函数是否被调用,for 循环已经完成,i 被赋予了最终的值3。

我的理解:
题目1返回的是函数,

  • 相当于返回的是[lambda(2,i), lambda(2,i), lambda(2,i), lambda(2,i)],
  • 但是函数是在运行的时候才需要使用到i的
  • 然而i是个可变变量,在运行时后,i已经经历完for循环了
  • 此时的i的值是3

(如果有不对的地方,欢迎提出~)

问题3:那题目2为啥返回[0,2,4,6]?

搞懂这个问题之前,我们先要记住问题1的答案,题目2返回的是什么?是函数吗?不是,是生成器!啥是生成器?emmm,好像懂但是又好像不懂?没关系,下面来搞明白一下下。

啥是生成器:

  • 返回yield输出的函数
  • (列表表达式)

生成器最重要的特点

当然仅仅知道啥是生成器还是不够的,还应该知道生成器的特点,生成器最大的特点就是惰性计算,即一次只计算出一个值。

那么第二题可以理解为,函数返回的是生成器,而且生成器里面的i值在for循环赋值的时候就已经被确定了。相当于返回的是lambda(0,x), lambda(1,x),lambda(2,x), lambda(3,x),通过next取值,然后进行计算。

相关文章

  • python陷阱(一):两道关于闭包的题

    两道题目 题目1 题目2 输出 题目1 题目2 带你探究为什么? 问题1:题目1和题目2函数返回分别是什么? 由上...

  • python闭包学习

    参考文章 python闭包python闭包一步一步教你认识Python闭包深入浅出python闭包

  • python函数之闭包

    目录 python函数之闭包什么是闭包python中的namespace闭包的条件闭包的优点 python函数之闭...

  • Python 闭包使用注意点

    1 Python 闭包 今天,聊下 python 的闭包。在函数编程中经常用到闭包。 闭包是什么,它是怎么产生的及...

  • Python装饰器

    【写在前面】在学习python装饰器之前呢,先要对python中的闭包函数有一定的理解,附上一篇关于闭包的文章(写...

  • python中的函数

    关于python中的值传递和址传递 匿名函数 缺省函数 闭包 装饰器

  • Python的自定义超时机制——装饰器的妙用

    装饰器 关于装饰器的入门,可以参考这篇文章:12步轻松搞定python装饰器简单来说,装饰器其实就是一个闭包(闭包...

  • Python作用域,local,global的scope

    重点: 局部作用域与全局作用域: 还有就是关于Python中的闭包。 闭包的定义:如果在一个内部函数里,对在外部函...

  • python高级之闭包

    python高级之闭包 什么是闭包? 闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结...

  • Python 中的作用域规则和闭包简析

    在对Python中的闭包进行简单分析之前,我们先了解一下Python中的作用域规则。关于Python中作用域的详细...

网友评论

      本文标题:python陷阱(一):两道关于闭包的题

      本文链接:https://www.haomeiwen.com/subject/onzgsctx.html