鱼C论坛

 找回密码
 立即注册
查看: 1069|回复: 7

[已解决]请问一下这个还是看不懂

[复制链接]
发表于 2019-8-2 16:19:52 | 显示全部楼层 |阅读模式

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

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

x
零基础Python的20章闭包的这一题:
def funX():
    x = 5
    def funY():
        nonlocal x
        x += 1
        return x
    return funY

a = funX()
print(a())
print(a())
print(a())
为什么输出6,7,8,谢谢大佬
最佳答案
2019-8-2 19:18:34
本帖最后由 jackz007 于 2019-8-2 19:19 编辑
winter宇 发表于 2019-8-2 18:58
所以就是将最内的函数赋给a(),然后在我那道题中就是当a()已经被赋予funY()的函数之后,每一次print(a( ...


        是这样,x 的值在 a = funX() 的时候被初始化为 5,此后,每次调用 a() 都会导致 x 的值增加 1,于是,就有了 6,7,8 的结果。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-8-2 16:33:32 | 显示全部楼层
本帖最后由 jackz007 于 2019-8-2 16:39 编辑
  1. def funX():
  2.     x = 5
  3.     def funY():
  4.         nonlocal x
  5.         x += 1
  6.         return x
  7.     return funY

  8. a = funX()           # 调用函数 funX(),初始化 x 的值为 5,返回值为函数 funY() 的调用地址。也就是说,a 的值就是 funY() 的调用地址,此后,表达式 a() 就是调用函数 funY()
  9. print(a())           # 调用一次 funY(), 外部变量 x 的值加 1,返回 x = 6
  10. print(a())           # 调用一次 funY(), 外部变量 x 的值加 1,返回 x = 7
  11. print(a())           # 调用一次 funY(), 外部变量 x 的值加 1,返回 x = 8
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-2 16:41:43 | 显示全部楼层

为什么funY()可以被调用啊,这个不是内嵌函数吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-2 17:06:07 | 显示全部楼层
本帖最后由 jackz007 于 2019-8-2 18:24 编辑
winter宇 发表于 2019-8-2 16:41
为什么funY()可以被调用啊,这个不是内嵌函数吗?


        没错,funY() 本来是内嵌函数,根据标识符的作用域规则,这个函数只能在 funX() 的范围内可见,从外部是不可见的。可是,a = funX() 的结果,又把 funY() 的调用地址传递给了变量 a,于是,a 就成为了函数 funY() 的代理,在 a  的作用域范围内,通过 a() 就可以调用到函数 funY() 本身了。

        考察一下下面的函数可以进一步加深理解:
  1. def fun1():
  2.     def fun2():
  3.         def fun3():
  4.             def fun4():
  5.                 def fun5():
  6.                     print("hello, world!")
  7.                 print("in fun4() . . .")
  8.                 return fun5
  9.             print("in fun3() . . .")
  10.             return fun4()
  11.         print("in fun2() . . .")
  12.         return fun3()
  13.     print("in fun1() . . .")
  14.     return fun2()

  15. a = fun1()
  16. a()
  17. a()
  18. a()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-8-2 18:57:19 | 显示全部楼层
所以就是将最内的函数赋给a(),然后在我那道题中就是当a()已经被赋予funY()的函数之后,每一次print(a())的话x的值也会改变并且保存,这样我3次print(a())3次x的值也分别不一样的吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-2 18:58:28 | 显示全部楼层
jackz007 发表于 2019-8-2 17:06
没错,funY() 本来是内嵌函数,根据标识符的作用域规则,这个函数只能在 funX() 的范围内可见 ...


所以就是将最内的函数赋给a(),然后在我那道题中就是当a()已经被赋予funY()的函数之后,每一次print(a())的话x的值也会改变并且保存,这样我3次print(a())3次x的值也分别不一样的吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-2 19:18:34 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-8-2 19:19 编辑
winter宇 发表于 2019-8-2 18:58
所以就是将最内的函数赋给a(),然后在我那道题中就是当a()已经被赋予funY()的函数之后,每一次print(a( ...


        是这样,x 的值在 a = funX() 的时候被初始化为 5,此后,每次调用 a() 都会导致 x 的值增加 1,于是,就有了 6,7,8 的结果。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-2 19:20:34 | 显示全部楼层
jackz007 发表于 2019-8-2 19:18
是这样,x 的值在 a = funX() 的时候被初始化为 5,此后,每次调用 a() 都会导致 x 的值增加 1 ...

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-3 17:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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