Jerry~Mouse 发表于 2021-8-27 22:13:53

函数内包课后习题的问题

本帖最后由 Jerry~Mouse 于 2021-8-27 22:19 编辑

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
应该说还是没有明白funY后面不加()的意义

白two 发表于 2021-8-27 23:27:57

本帖最后由 白two 于 2021-8-27 23:38 编辑

将函数作为返回值是高阶函数,称为闭包
带括号,调用的是函数的return结果,需要等待函数执行完成的结果
不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不需等该函数执行完成
funX() 函数 return 的是 funY 函数的一个引用,这个时候就像但与 a 指向这个函数的本体, a 就相当于 funY , a() 就相当于 funY()

def funX():
    x = 5
    def funY():
      nonlocal x
      x += 1
      return x
    print(funY)
    return funY

a = funX()
print(a())
print(a())
print(a())
print(a)

结果:
<function funX.<locals>.funY at 0x00000213E7F19E50>
6
7
8
<function funX.<locals>.funY at 0x00000213E7F19E50>

你看 a 和 funY 指向的是同一个函数对象

Jerry~Mouse 发表于 2021-8-28 01:02:38

白two 发表于 2021-8-27 23:27
将函数作为返回值是高阶函数,称为闭包
带括号,调用的是函数的return结果,需要等待函数执行完成的结果
...

其实我这道题不解的是,第一次a = funx()执行完之后,a返回了一个函数,funY,这个funY的值永远是6,我就觉得后面无论怎么调用这个a(),它的值都应该是funY调用出来的结果,永远都为6

Jerry~Mouse 发表于 2021-8-28 01:10:52

本帖最后由 Jerry~Mouse 于 2021-8-28 01:22 编辑

白two 发表于 2021-8-27 23:27
将函数作为返回值是高阶函数,称为闭包
带括号,调用的是函数的return结果,需要等待函数执行完成的结果
...

难道说a = funx() 这个语句是不执行funY里面的内容的吗,仅仅就是把a指向了funY?其实此时x 还是= 5?
然后a()就表示 我现在开始调用funY这个函数了 到现在为止x才开始变化?此时x才变为了6?
然后再下面的a()就是从x = 6的基础上调用funY这个函数的吗?
我可以这样理解吗

白two 发表于 2021-8-28 10:33:55

本帖最后由 白two 于 2021-8-28 10:45 编辑

Jerry~Mouse 发表于 2021-8-28 01:10
难道说a = funx() 这个语句是不执行funY里面的内容的吗,仅仅就是把a指向了funY?其实此时x 还是= 5?
...

funY 哪来的值呢?他只是一个函数罢了
可以这么理解,但我感觉它的机制像是重新给 a 开辟了一块内存来存储 funY 的逻辑:

def funX():
    x = 5
    def funY():
      nonlocal x
      x += 1
      return x
    return funY

print(id(funX))
a = funX
print(id(a))

b = funX()
c = funX()
print(funX())
print(b)
print(c)
print(id(b))
print(id(c))

print(b())
print(b())
print(c())


结果:

1363293958208
1363293958208
<function funX.<locals>.funY at 0x0000013D6B18A3A0>
<function funX.<locals>.funY at 0x0000013D6B188E50>
<function funX.<locals>.funY at 0x0000013D6B18A310>
1363301404240
1363301409552
6
7
6

你看,三个函数funx(),b,c,全是 function funX.<locals>.funY 对象,只是地址不一样罢了,

你看如果直接 a = funX 的话,就是 a 指向 funX 的内存,调用 a 改的 x 是啥值, funX 的 x 就是啥值
但是闭包的话就相当于再开了一块内存,但是函数依然是 funY ,所以 x 初始值依然是 5,但 b,c的内存地址不一样,所以它俩互不影响,但是你是直接三次调用 a 啊

Jerry~Mouse 发表于 2021-8-28 19:02:23

白two 发表于 2021-8-28 10:33
funY 哪来的值呢?他只是一个函数罢了
可以这么理解,但我感觉它的机制像是重新给 a 开辟了一块内存来存 ...

所以b = funx()和c = funx()
这两个funx()不一样对吧,就如同
a =
b =
这两个列表互不干涉,是这个意思吧

白two 发表于 2021-8-28 20:25:56

Jerry~Mouse 发表于 2021-8-28 19:02
所以b = funx()和c = funx()
这两个funx()不一样对吧,就如同
a =


嗯,相当于复刻了一份 funY
页: [1]
查看完整版本: 函数内包课后习题的问题