鱼C论坛

 找回密码
 立即注册
查看: 2334|回复: 20

对20将讲里对闭包存在的疑问

[复制链接]
发表于 2017-1-25 00:36:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 窥基的直 于 2017-1-25 19:32 编辑

一级萌新,初来驾到,请多多指教,
问题:小甲鱼在视频里提了,俩中对闭包的处理方式如下:
def funq():
        q = [5]
        def funp():
                q[0]  *= q[0]
                return q[0]
        return funp()

def funq():
        x = 5
        def funp():
                nonlocal x
                x *= x
                return x
        return funp()
这俩种方法根据我的理解类似于将外部数值的传入内部函数,于是乎我就想用如下代码模拟:
def funx():
        x = 5
        def funy(x):
                x *= x
                return x
        return funy(x)

虽然结果一样,但不确定还是不是闭包了。。。。还有就是我不知道我这样写的与上俩种方法有没有本质上的区别,
或者说上俩种的方法的优势在哪。。以及闭包的实际意义是什么。。第三种方法是否有某些局限性(因为是大半夜 看完的视频,可能之前有过类似的问题,或者我没有认真的自己去思考,但实在是太迟了已经实在是无心去寻找资料,还请大神们多多包涵哈= =为我解答)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-1-25 00:39:45 | 显示全部楼层
又回去看了一下视频。根据概念应该就是闭包没错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-25 00:46:26 | 显示全部楼层
是想跳过函数数值传导的过程 ,直接调用或修改么= =,形参招谁惹谁了。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-25 13:05:13 | 显示全部楼层
。。。没人回答。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-25 14:06:16 | 显示全部楼层
开启回复给鱼币模式= =真的没人回我么。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-25 14:48:06 | 显示全部楼层

回帖奖励 +1 鱼币

  1. >>> def funx():
  2.         x = 5
  3.         def funy(x):
  4.                 x *= x
  5.                 return x
  6.         return funy(x)

  7. >>> import dis
  8. >>> dis.dis(funx)
  9.   2           0 LOAD_CONST               1 (5)
  10.               3 STORE_FAST               0 (x)

  11.   3           6 LOAD_CONST               2 (<code object funy at 0x019CBC50, file "<pyshell#1>", line 3>)
  12.               9 LOAD_CONST               3 ('funx.<locals>.funy')
  13.              12 MAKE_FUNCTION            0
  14.              15 STORE_FAST               1 (funy)

  15.   6          18 LOAD_FAST                1 (funy)
  16.              21 LOAD_FAST                0 (x)
  17.              24 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
  18.              27 RETURN_VALUE
  19. >>> def funq():
  20.         x = 5
  21.         def funp():
  22.                 nonlocal x
  23.                 x *= x
  24.                 return x
  25.         return funp

  26. >>> dis.dis(funq)
  27.   2           0 LOAD_CONST               1 (5)
  28.               3 STORE_DEREF              0 (x)

  29.   3           6 LOAD_CLOSURE             0 (x)
  30.               9 BUILD_TUPLE              1
  31.              12 LOAD_CONST               2 (<code object funp at 0x019B27F0, file "<pyshell#5>", line 3>)
  32.              15 LOAD_CONST               3 ('funq.<locals>.funp')
  33.              18 MAKE_CLOSURE             0
  34.              21 STORE_FAST               0 (funp)

  35.   7          24 LOAD_FAST                0 (funp)
  36.              27 RETURN_VALUE
  37. >>>
复制代码


LOAD_CLOSURE
MAKE_CLOSURE
这两个是构造闭包的指令。
自己看,仔细体会
严格按照闭包的语法格式书写。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-1-25 15:15:35 | 显示全部楼层
SixPy 发表于 2017-1-25 14:48
LOAD_CLOSURE
MAKE_CLOSURE
这两个是构造闭包的指令。

想说还是一头雾水。。。。只看出了里面的不同之处,具体意义还不明白,能不能帮我分析一下,具体区别是啥。。。闭包的语法格式是不能再函数内部里里将参数通过形参传递到内部函数里吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-25 19:32:49 | 显示全部楼层
一天过去了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-26 09:07:01 | 显示全部楼层

回帖奖励 +1 鱼币

我是新人小白,说下自己的理解
版主的解释我没能彻底理解。只是看出来第一种写法不是闭包,第二种是。写法1只是在funx()里给x赋值,然后调用funy。其实写法1不定义funx也是没差别的。
我理解的闭包就是nonlocal的字母意思,非局部变量的意思,避免在内部函数中创建于外部函数同名的变量,从而把外部函数的同名变量shadow掉。貌似不是你说的传到形参的作用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-28 22:56:42 | 显示全部楼层
本帖最后由 窥基的直 于 2017-1-28 23:01 编辑

@小甲鱼
好像没什么人回答了。。。老师能来解答一下么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-1-28 22:58:02 | 显示全部楼层
无聊才上线 发表于 2017-1-26 09:07
我是新人小白,说下自己的理解
版主的解释我没能彻底理解。只是看出来第一种写法不是闭包,第二种是。写法 ...

。。不是灰常的清楚,不过好像闭包不一定要用到nonlocal吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-7 10:51:29 | 显示全部楼层

回帖奖励 +1 鱼币

你三个都不是闭包吧,闭包的特征是return的函数本身,不带()的,闭包是在修饰器上用的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-7 11:12:54 | 显示全部楼层

回帖奖励 +1 鱼币

我还没有看到那里,无法回答啊,同是萌新小白,一起共勉!
另:楼主,开出SSR了吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2017-3-8 07:15:29 | 显示全部楼层

回帖奖励 +1 鱼币

提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-8 17:23:29 | 显示全部楼层

回帖奖励 +1 鱼币

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一  组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性

我觉得这个定义还是很好理解的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-8 17:36:34 | 显示全部楼层
根据这句话,其实我们自己就可以总结出在python语言中形成闭包的三个条件,缺一不可:
1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套
2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量
3)外部函数必须返回内嵌函数——必须返回那个内部函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-8 18:08:30 | 显示全部楼层

回帖奖励 +1 鱼币

仅仅个人理解,有错误欢迎指正,我一个个问题解答哈
问题一,什么是闭包
在一个嵌套函数中,只要满足了以下两个条件,就算达成了闭包~:
1,外层函数返回了内层函数
2,内层函数使用了外层函数的变量或者参数
问题二,两种处理方法的区别:
第一种用了列表来进行参数传递,因为列表是可变的数据类型,所以内层函数可以在他自己的作用域内找到列表
第二种传递的是一个整数数据类型,但是因为整形是一个不可变类型,当变量发生变化,内层函数是无法通过x引用到对应的值,所以会认为x没有定义,那么就需要用nonlocal来告诉编译器x是外层函数的变量
第三个问题,闭包的作用,我个人学到现在,理解下来,发现了两种用处:
1,一个是延迟输出,你可以先定义外层函数,然后再有需要的时候,调用内层函数
2,还有一个用在修饰符上面,这个你可以参考论坛里的扩展阅读修饰符部分的知识

至于,你说的第三种局限性,我表示。。。┑( ̄Д  ̄)┍我不知道你说的是功能的局限还是语法上的

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-9 09:25:32 | 显示全部楼层

回帖奖励 +1 鱼币

是闭包没错  但是 我要说的 里面的X是新建的变量x  不是外面那层的x了  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-15 10:15:17 | 显示全部楼层

回帖奖励 +1 鱼币

应该是闭包没错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-20 19:43:13 | 显示全部楼层

回帖奖励 +1 鱼币


应该是闭包没错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-28 04:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表