马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 Python初学者8号 于 2021-1-19 19:52 编辑
看了视频不是很懂,我又看了这个人的 https://www.bilibili.com/video/B ... 333.788.videocard.0 和 https://www.bilibili.com/video/B ... 1162869546400874586
然后大概懂了
我自己写了一个代码,有两种情况的返回值。如下
1.return f2()
def f1():
print('我是一楼')
def f2():
print('我是二楼')
return f2()
运行结果是
运行结果是
函数f1
参数 :没有
作用是:打印“我是一楼”和定义f2, 其中,很重要的是,在定义f2的过程中并不会打印“我是二楼”!!切记!!
其返回值是 f2()的值(也就是函数f2的返回值),当然很明显的是f2的这里返回值是None了
函数f2
参数 :没有
作用是:打印“我是二楼”
返回值为None
如此以来,给a赋值的过程就是:就是赋值一个None,但是在赋值的同时也是运行了(创建了)一个函数对象f1,并且(通过引用的过程)进行了调用f1。
在执行f1的时候,首先第一步是打印我是一楼,然后再进行f2的定义(并且会打印我是二楼),最后所以会打印出两个print
所以也才有打印a的时候就是None
2.return f2
def f1():
print('我是一楼')
def f2():
print('我是二楼')
return f2
运行结果是
运行结果是<function f1.<locals>.f2 at 0x000001690866E9D0>
很明显这里出现了区别(其实只要懂调用的方法就好了。)原因就是:
在return中,我们这里是f2而不是f2(),这是有很大区别的。 return f2()的情况我刚解释了,这句就是调用f2()并且将f2本身的返回值作为f1的返回值作为结果返回;
而如果是return f2的话,这里不仅仅没有进行调用f2的这个过程(打印出我是二楼),而且返回的是f2的函数内存地址
看这里就知道了
<i><font color="#008000">f1
<function f1 at 0x000001690849CF70>
id(f1)
1550622248816
0x000001690849CF70 == 1550622248816
True</font></i>
这里啊别犯错f2了,因为f2不能直接在控制台调用,只能直接调用f1.
所以这就说明了,当直接返回f2(而不是f2())的时候,实际是返回了函数对象f2的地址
所以,这里要明白:1.函数在调用的时候才会执行(赋值本身就包含调用) # 函数在定义的时候,函数体不会进行执行(如上面不打印我是二楼)
2.单纯只叫名字f1,f2不是调用
第二个内容就是闭包,这里我想讨论的是复合函数(哈哈,看到弹幕有人这么说的)
在我看懂闭包前后我写了两个函数,然后我现在来讨论一下这个关于函数的嵌套的问题。
1 。看懂闭包前:def f1(value):
def f2(value):
u = value ** 2
return u
y = f2(value) + 1
return y
y_1= f1(3)
print(y_1)
他的结果是正确的运行,是“10”。
2 看懂闭包之后:def f1(x):
u = x**2
def f2(u):
return u + 1
return f2(u)
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。这不是更高效? 我使用闭包的意义何在?这里看起来是调用了外部变量,实际上么可用没用。
感觉像是在给一个很好的数据结构,因为这个内部函数调用外部变量的时候,往往可能很多其他的函数也在调用,但是如果我想要改变咋整
算了,这里理解以后再写,现在没有遇到实例写起来很傻逼
|