鱼C论坛

 找回密码
 立即注册
查看: 3089|回复: 8

求大佬们帮忙解决一下这个闭包问题,鱼币答谢

[复制链接]
发表于 2020-3-2 20:42:53 | 显示全部楼层 |阅读模式

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

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

x
  1. # 第一版运行
  2. def funX():
  3.     x = 5
  4.     print(x,'\'')
  5.     print("Running X")
  6.     def funY():
  7.         nonlocal x
  8.         x += 1
  9.         print("Running Y")
  10.         return x
  11.     return funY
  12. print(funX()())
  13. print(funX()())
  14. print(funX()())
  15. print()
  16. a = funX()
  17. print(a())
  18. print(a())
  19. print(a())
复制代码

运行结果:
5 '
Running X
Running Y
6
5 '
Running X
Running Y
6
5 '
Running X
Running Y
6

5 '
Running X
Running Y
6
Running Y
7
Running Y
8
我这前半段代码用的print(funx()()),三次答案都是6,而且都有Running X和Running Y的过程,但用了print(a()())后,只有第一次结果有Running X剩下都是只有Running Y,这是为什么?
还有接下来这段
  1. # 第二版运行
  2. def funX():
  3.     x = 5
  4.     print(x,'\'')
  5.     print("Running X")
  6.     def funY():
  7.         nonlocal x
  8.         x += 1
  9.         print("Running Y")
  10.         return x
  11.     return funY()

  12. print(funX())
  13. print(funX())
  14. print(funX())
  15. print()
  16. a = funX()
  17. print(a)
  18. print(a)
  19. print(a)
复制代码

运行结果:
5 '
Running X
Running Y
6
5 '
Running X
Running Y
6
5 '
Running X
Running Y
6

5 '
Running X
Running Y
6
6
6
这一段我把return funY改成了renturn funY(),后面依然有a=funX()的复制,为什么这次的x=5就重新定义了,三次结果都是6,但依然只有第一次结果有Running X剩下都是只有Running Y
请问这个return funX加不加括号的意义是什么,为啥差距这么大,求大佬解释,谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-3-2 20:44:33 | 显示全部楼层

回帖奖励 +5 鱼币

a = funX() 这一句已经调用了一次 funX,之后调用 a 只是单纯地在调用 funY,并不会重新调用 funX。

funX()() 会调用一次 funX。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-2 21:08:09 | 显示全部楼层

回帖奖励 +5 鱼币

本帖最后由 一个账号 于 2020-3-2 22:59 编辑

为什么第一次调用 a() 会跑到 funX() 那里
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-2 21:08:43 | 显示全部楼层

回帖奖励 +5 鱼币

两个程序里的 a 都是 funX() 函数的返回值,只是第一次的 a = funY,所以后面的每次 print(a())  都相当于 print(funY()),所以只会打印 ......Y 这一句,至于为什么 x 会改变,因为此时的 x 与 funY() 函数在一个引用环境,简单点说就是 x 与 funY() 打包在了一起,这就是 “闭包”,所以 x 才会变化。
第二次的 a 相当于 funY() , print(a) 即是 print(funY()),所以同样的只会打印 ....Y 这一句,至于为什么 x 不会改变,则与上面相反了,此时 x 并没有脱离创建它的环境,即仍在 funX() 空间内,并没有与 funY() 函数绑定,所以对于 funY() 来说,这个 x 是外部函数变量,所以不会被改变。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-2 22:21:10 From FishC Mobile | 显示全部楼层
zltzlt 发表于 2020-3-2 20:44
a = funX() 这一句已经调用了一次 funX,之后调用 a 只是单纯地在调用 funY,并不会重新调用 funX。

而  ...

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-2 22:21:58 From FishC Mobile | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-3-2 21:08
两个程序里的 a 都是 funX() 函数的返回值,只是第一次的 a = funY,所以后面的每次 print(a())  都相当于  ...

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-2 22:26:09 From FishC Mobile | 显示全部楼层
一个账号 发表于 2020-3-2 21:08
看了以这个程序,有两点我感到奇怪:

1. 为什么第一次调用 a() 会跑到 funX() 那里

1.a=funX()相当于调用了funY引用,就像下一楼回答的一样 2.的确没有报错,而且这个return x是小甲鱼python课第20节的作业原代码,你可以去看一下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-15 09:06:16 | 显示全部楼层
小白前来学习一下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-15 09:30:34 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-30 09:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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