Torwnexial 发表于 2020-3-2 20:42:53

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

# 第一版运行
def funX():
    x = 5
    print(x,'\'')
    print("Running X")
    def funY():
      nonlocal x
      x += 1
      print("Running Y")
      return x
    return funY
print(funX()())
print(funX()())
print(funX()())
print()
a = funX()
print(a())
print(a())
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,这是为什么?
还有接下来这段
# 第二版运行
def funX():
    x = 5
    print(x,'\'')
    print("Running X")
    def funY():
      nonlocal x
      x += 1
      print("Running Y")
      return x
    return funY()

print(funX())
print(funX())
print(funX())
print()
a = funX()
print(a)
print(a)
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加不加括号的意义是什么,为啥差距这么大,求大佬解释,谢谢!

zltzlt 发表于 2020-3-2 20:44:33

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

而 funX()() 会调用一次 funX。

一个账号 发表于 2020-3-2 21:08:09

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

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

°蓝鲤歌蓝 发表于 2020-3-2 21:08:43

两个程序里的 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 是外部函数变量,所以不会被改变。

Torwnexial 发表于 2020-3-2 22:21:10

zltzlt 发表于 2020-3-2 20:44
a = funX() 这一句已经调用了一次 funX,之后调用 a 只是单纯地在调用 funY,并不会重新调用 funX。

而...

谢谢

Torwnexial 发表于 2020-3-2 22:21:58

°蓝鲤歌蓝 发表于 2020-3-2 21:08
两个程序里的 a 都是 funX() 函数的返回值,只是第一次的 a = funY,所以后面的每次 print(a())都相当于...

谢谢

Torwnexial 发表于 2020-3-2 22:26:09

一个账号 发表于 2020-3-2 21:08
看了以这个程序,有两点我感到奇怪:

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


1.a=funX()相当于调用了funY引用,就像下一楼回答的一样 2.的确没有报错,而且这个return x是小甲鱼python课第20节的作业原代码,你可以去看一下

aironeng 发表于 2020-12-15 09:06:16

小白前来学习一下

qq1151985918 发表于 2020-12-15 09:30:34

{:10_254:}
页: [1]
查看完整版本: 求大佬们帮忙解决一下这个闭包问题,鱼币答谢