鱼C论坛

 找回密码
 立即注册
查看: 1374|回复: 0

[技术交流] 关于 闭包 的笔记

[复制链接]
发表于 2021-1-19 18:41:34 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 Python初学者8号 于 2021-1-19 19:52 编辑

看了视频不是很懂,我又看了这个人的 https://www.bilibili.com/video/B ... 333.788.videocard.0https://www.bilibili.com/video/B ... 1162869546400874586
然后大概懂了

我自己写了一个代码,有两种情况的返回值。如下

1.return f2()

  1. def f1():
  2.     print('我是一楼')
  3.     def f2():
  4.         print('我是二楼')
  5.     return f2()
复制代码


运行
  1. a = f1()
复制代码

结果是
  1. 我是一楼
  2. 我是二楼
复制代码


运行
  1. print(a)
复制代码

结果是
  1. None
复制代码


函数f1
参数 :没有
作用是:打印“我是一楼”和定义f2,      其中,很重要的是,在定义f2的过程中并不会打印“我是二楼”!!切记!!
其返回值是  f2()的值(也就是函数f2的返回值),当然很明显的是f2的这里返回值是None了

函数f2
参数 :没有
作用是:打印“我是二楼”
返回值为None

如此以来,给a赋值的过程就是:就是赋值一个None,但是在赋值的同时也是运行了(创建了)一个函数对象f1,并且(通过引用的过程)进行了调用f1。
在执行f1的时候,首先第一步是打印我是一楼,然后再进行f2的定义(并且会打印我是二楼),最后所以会打印出两个print
所以也才有打印a的时候就是None


2.return f2

  1. def f1():
  2.     print('我是一楼')
  3.     def f2():
  4.         print('我是二楼')
  5.     return f2
复制代码


运行
  1. a = f1()
复制代码

结果是
  1. 我是一楼
复制代码


运行
  1. print(a)
复制代码

结果是
  1. <function f1.<locals>.f2 at 0x000001690866E9D0>
复制代码


很明显这里出现了区别(其实只要懂调用的方法就好了。)原因就是:

在return中,我们这里是f2而不是f2(),这是有很大区别的。 return f2()的情况我刚解释了,这句就是调用f2()并且将f2本身的返回值作为f1的返回值作为结果返回;
而如果是return f2的话,这里不仅仅没有进行调用f2的这个过程(打印出我是二楼),而且返回的是f2的函数内存地址

看这里就知道了
  1. <i><font color="#008000">f1
  2. <function f1 at 0x000001690849CF70>
  3. id(f1)
  4. 1550622248816
  5. 0x000001690849CF70 == 1550622248816
  6. True</font></i>
复制代码


这里啊别犯错f2了,因为f2不能直接在控制台调用,只能直接调用f1.

所以这就说明了,当直接返回f2(而不是f2())的时候,实际是返回了函数对象f2的地址



                               
登录/注册后可看大图


所以,这里要明白:1.函数在调用的时候才会执行(赋值本身就包含调用)                       #    函数在定义的时候,函数体不会进行执行(如上面不打印我是二楼)
2.单纯只叫名字f1,f2不是调用





                               
登录/注册后可看大图

第二个内容就是闭包,这里我想讨论的是复合函数(哈哈,看到弹幕有人这么说的)

在我看懂闭包前后我写了两个函数,然后我现在来讨论一下这个关于函数的嵌套的问题。

1 。看懂闭包前:
  1. def f1(value):

  2.     def f2(value):
  3.         u = value ** 2
  4.         return u
  5.     y = f2(value) + 1
  6.     return y

  7. y_1= f1(3)
  8. print(y_1)
复制代码
他的结果是正确的运行,是“10”。

2 看懂闭包之后:
  1. def f1(x):
  2.     u = x**2
  3.     def f2(u):
  4.         return u + 1
  5.     return f2(u)
  6. print(f1(1))
复制代码
这里也是正常运行了。

++++++++++++++++++++++++++++
首先我们给出一个复合函数的形式  y = u     u =u(x)
好了我们现在讨论函数1,这里面,首先我们看内部函数是不是调用了外部函数的参数。这里严格来说的话,是调用了,因为value是从f1传递过来的,然后再f2中被使用了。
然后我们看看数学形式的实现,这里面很明显是使用f2作为内层函数(哈哈哈,是真的内层,就是u),然后使用f1实现y=u这个外部函数。
这里值得注意的是,我使用了return u 来作为后面的  y = f2(value) + 1 的基础值。
所以这个函数的方法就是单纯的嵌套,而且傻逼,完全没有必要这样做。还不如这样:不要内部函数,而是直接写u = value ** 2,再写y = f2(value) + 1。这不是更高效?  我使用闭包的意义何在?这里看起来是调用了外部变量,实际上么可用没用。


感觉像是在给一个很好的数据结构,因为这个内部函数调用外部变量的时候,往往可能很多其他的函数也在调用,但是如果我想要改变咋整
算了,这里理解以后再写,现在没有遇到实例写起来很傻逼

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-1 13:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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