广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python中闭包与lambda的作用域解析
  • 166
分享到

Python中闭包与lambda的作用域解析

python 2022-08-08 13:08:13 166人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

本篇文章给大家带来了关于python的相关知识,其中主要整理了关于lambda的作用域的相关问题,还有Python中闭包的相关内容,下面一起来看一下,希望对大家有帮助。【相关推荐:python3视频教程 】Python闭包与lambda的作

本篇文章给大家带来了关于python的相关知识,其中主要整理了关于lambda的作用域的相关问题,还有Python中闭包的相关内容,下面一起来看一下,希望对大家有帮助。

【相关推荐:python3视频教程

Python闭包与lambda的作用域

lambda写法

def fun():
    for i in range(3):
        yield lambda x : x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

闭包的写法

def fun():
    result = []
    for i in range(3):
        def demo(x):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

上面两种写法的结果都是2,4,6,按最初的想法结果应该是0,2,6。

问题原因:

问题的本事在python的变量查找规则,LEGB(local,enclousing,global,bulitin),上面的例子中,i就是在闭包作用域(enclousing),而Python的闭包是迟绑定,闭包中用到的变量i的值,是在内部函数被调用时查找到的。

解决办法

将闭包作用域变为局部作用域

lambda写法

def fun():
    for i in range(3):
        yield lambda x, i = i: x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

闭包写法

def fun():
    result = []
    for i in range(3):
        def demo(x, i=i):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

以上输出结果0,2,6

另一种情况:

def fun():
    for i in range(3):
        yield lambda x : x * i
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))

输出结果还是2,4,6

问题原因

fun()方法返回的生成器(或迭代器),并没有真正的执行,而是在每次调用的时候进行执行。

在遍历后执行打印时,i这个变量使用的是最后调用的值。将lambda看作闭包方法的话,变量i值还是闭包作用域(no local)

python当中的坑(闭包与lambda)

先来看一个栗子

def create():
    return [lambda x:i*x for i in range(5)]
 
for i in create():
    print(i(2))

结果:

8

8

8

8

8

create函数的返回值时一个列表,列表的每一个元素都是一个函数 -- 将输入参数x乘以一个倍数i的函数。预期的结果时0,2,4,6,8. 但结果是5个8,意外不意外。

由于出现这个陷阱的时候经常使用了lambda,所以可能会认为是lambda的问题,但lambda表示不愿意背这个锅。问题的本质在与python中的属性查找规则,LEGB(local,enclousing,global,bulitin),在上面的例子中,i就是在闭包作用域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询得到的

解决办法也很简单,那就是变闭包作用域为局部作用域。

def create():
    return [lambda x, i=i:i*x for i in range(5)]
 
for i in create():
    print(i(2))

换种写法:

def create():
    a = []
    for i in range(5):
        def demo(x, i=i):
            return x*i
        a.append(demo)
    return a
 
for i in create():
    print(i(2))

以上两种写法是一样的

结果:

0
2
4
6
8

再来一个问题相似的栗子

代码很简单:(声明:python3问题)

nums = range(2,20)
for i in nums:
    nums = filter(lambda x: x==i or x%i, nums)
print(list(nums))

结果:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

同样按照正常的逻辑结果应该为:

[2, 3, 5, 7, 11, 13, 17, 19]

问题产生的原因:

  • 在python3当中filter()函数返回的是一个迭代器,因此并没有做真正的执行,而是在每次调用的时候执行(python2中filter()返回的值列表,无此现象)
  • 在遍历后执行打印时,现在执行循环当中的函数,同上面一个栗子的问题,i这个变量使用的是最后调用时的值,与以上栗子不同的是以上栗子用的是内嵌作用域的值,而这个栗子用的是全局i的值

修改代码:

nums = range(2,20)
for i in nums:
    nums = filter(lambda x,i=i: x==i or x%i, nums)
print(list(nums))

结果:

[2, 3, 5, 7, 11, 13, 17, 19]

【相关推荐:Python3视频教程 】

以上就是Python中闭包与lambda的作用域解析的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: Python中闭包与lambda的作用域解析

本文链接: https://www.lsjlt.com/news/33554.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python中闭包与lambda的作用域解析
    本篇文章给大家带来了关于Python的相关知识,其中主要整理了关于lambda的作用域的相关问题,还有Python中闭包的相关内容,下面一起来看一下,希望对大家有帮助。【相关推荐:Python3视频教程 】Python闭包与lambda的作...
    99+
    2022-08-08
    python
  • Python中闭包与lambda的作用域怎么写
    这篇文章主要介绍“Python中闭包与lambda的作用域怎么写”,在日常操作中,相信很多人在Python中闭包与lambda的作用域怎么写问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中闭包与l...
    99+
    2023-07-02
  • JavaScript 中的作用域与闭包
    目录一、JavaScript 是一门编译语言1.1 传统编译语言的编译步骤1.2 JavaScript 与传统编译语言的区别二、作用域(Scope)2.1 LHS查询 和 RHS查询...
    99+
    2022-11-13
  • Python编程中闭包的变量作用域问题解析
    目录闭包闭包中的变量闭包 ​ 在我们使用返回函数的时候,由于我们在一个函数中需要返回另一个函数,因此,我们在这个函数中就需要重新定义一个函数。而这样,就造成了我们的函数嵌...
    99+
    2022-11-12
  • 你真的了解JavaScript的作用域与闭包吗
    目录一、作用域二、闭包总结一、作用域 1.作用域总体来说就是根据名称查找变量的一套规则。JS查找变量的方式有两种:LHS和RHS。 LHS(left hand side)大致可以理解...
    99+
    2022-11-13
  • Javascript之作用域、作用域链、闭包的示例分析
    这篇文章主要介绍Javascript之作用域、作用域链、闭包的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么是作用域?作用域是一种规则,在代码编译阶段就确定了,规定了变量...
    99+
    2022-10-19
  • Javascript的作用域、作用域链以及闭包详解
    一、javascript中的作用域 ①全局变量-函数体外部进行声明 ②局部变量-函数体内部进行声明 1)函数级作用域 javascript语言中局部变量不同于C#、Java等高级语言...
    99+
    2022-11-13
  • JavaScript深入理解作用域链与闭包详情
    目录深入作用域链与闭包作用域链[[Environment]]完善环境记录闭包函数实例什么是闭包变量绑定同一个闭包总结深入作用域链与闭包 为什么要把作用域链和闭包放在一起讲呢,它们有什...
    99+
    2022-11-13
  • JavaScript的闭包与变量作用域介绍
    这篇文章主要讲解了“JavaScript的闭包与变量作用域介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript的闭包与变量作用域介绍”吧!...
    99+
    2022-10-19
  • 基于Python函数的作用域规则和闭包(详解)
    作用域规则 命名空间是从名称到对象的映射,Python中主要是通过字典实现的,主要有以下几个命名空间: 内置命名空间,包含一些内置函数和内置异常的名称,在Python解释器启动时创建,一直保存到解释器退出。...
    99+
    2022-06-04
    详解 函数 规则
  • 深入解析Python中函数的参数与作用域
    传递参数 函数传递参数时的一些简要的关键点: 参数的传递是通过自动将对象赋值给本地变量名来实现的。所有的参数实际上都是通过指针进行传递的,作为参数被传递的对象从来不自动拷贝。 在函数内部的参数名的...
    99+
    2022-06-04
    函数 作用 参数
  • Javascript闭包的作用与使用方法浅析
    目录一、变量的作用域二、如何从外部读取局部变量js 闭包(closure)是Javascript语言的一个难点,也是它的特色。 闭包的作用:通过一系方法,将函数内部的变量(局部变量)...
    99+
    2023-01-18
    JavaScript闭包 JS闭包
  • Python中的闭包使用及作用
    目录1.什么是闭包2.闭包的实例3.闭包和装饰器的区别1.什么是闭包 当我们在外部函数中定义了一个内部函数,并且内部函数能够读取到外部函数内的变量,这种函数我们就称为闭包。简单来说,...
    99+
    2022-11-11
  • Python中的作用域与名字空间实例分析
    这篇文章主要介绍“Python中的作用域与名字空间实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中的作用域与名字空间实例分析”文章能帮助大家解决问题。变量只是一个符号从解释器的角...
    99+
    2023-07-05
  • 解密Python中的作用域与名字空间
    目录楔子变量只是一个符号变量的可见性LGB 规则局部变量是静态存储的LEGB 规则global 表达式属性空间小结楔子 前面我们介绍了栈帧,在里面看到了 3 个独立的名字空间:f_l...
    99+
    2023-02-28
    Python作用域 名字空间 Python作用域 Python 名字空间
  • js中作用域和作用域链及预解析的示例分析
    小编给大家分享一下js中作用域和作用域链及预解析的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!变量---->局部...
    99+
    2022-10-19
  • js中的this作用域全解析
    目录this作用域问题函数式调用方法调用模式在数组中的特例构造器调用模式call、apply、bind特殊情况——箭头函数综合例题this作用域问题 一般来说...
    99+
    2022-11-13
    js中this this作用域 js this作用域
  • 解读Python编程中的命名空间与作用域
    变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。 一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量...
    99+
    2022-06-04
    作用 空间 Python
  • JS难点同步异步和作用域与闭包及原型和原型链详解
    目录JS三座大山同步异步同步异步区别作用域、闭包函数作用域链块作用域闭包闭包解决用var导致下标错误的问题投票机闭包两个面试题原型、原型链原型对象原型链完整原型链图JS三座大山 同步...
    99+
    2022-11-12
  • 深入了解Rust中函数与闭包的使用
    目录闭包高阶函数发散函数闭包 Rust 的闭包由一个匿名函数加上外层的作用域组成,举个例子: fn main() {     let closure = |n: u32| ->...
    99+
    2022-11-13
    Rust 函数 闭包 Rust 函数 Rust 闭包
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作