Python的函数太丰富了,讲起来稍微有点费劲,如果给你一个函数简单使用的话,你大可不必深入去了解这个函数,但是作为一个学习者来说尽管不知道以后这个函数我们还会不会遇到,会不会使用到,我们也要尝试去和它打交道,深入的打交道,尽自己所理解的,去阐述它;
上一篇我们简单的配置了wing开发IDE,这篇,我们就结合一下它,来讲一下我们今天的主角,惰性函数,又称返回函数;
函数,我们知道它可以出现在参数里,像我们的高阶函数那样,当然,我们也能猜出来,它也可以出现在函数的返回值位置上,但是,实际上我们没有这样做过,因为,我们写函数的目的就是为了实现自己的想要的功能,这种实现需要是实时的,需要我们调用这个函数结束后,就能切身的体会到函数带给我们的便利,然而我们今天要讲的这个惰性函数,却是滞后的,如果你想显得自己很高深,用了它,请一定要小心,否则,会有麻烦的。
看个例子,简单认识一下惰性函数:
我们定一个函数,函数的功能是播报一条新闻,我们取名叫cast_News,当然,大部分情况下,新闻都是提前写好,按点播出的,所以,我们让这个播报新闻的动作(函数)先返回出去,至于具体谁来操作这个函数,我们不知道,因此,最外层,还要定一个顶层函数,这个顶层函数有一个参数,播报者的姓名,并且,这个函数的返回值是这个cast_News:
我们看下demo:
#/usr/bin/env Python3
#-*- encoding:UTF-8 -*-
'''
返回函数,顾名思义,就是一个函数的返回值是一个函数
Java、C#中返回一个函数,是不是听起来怪怪的,好像也不能吧
C/C++可以做到返回函数的指针
但是,像Python这种直接返回函数名的,真是大胆创新啊
'''
def cast(Name):
def cast_News():
print(Name,'现在开始播报新闻:巴铁痛揍印度阿三,大块人心!')
return cast_News
f1 = cast("appleyk") #cast 是一个懒惰函数,复杂点就是一个返回值是函数的函数,调用并不马上执行
f2 = cast('Bob') #注意,返回的函数地址不是同一个
print(f1)
print(f2)
print(f1==f2) #验证f1和f2是否指向的函数地址入口相等
f1()
f2() #这个时候,我们才真正的具体的将这个播报新闻这一行为给实施了
上面我们只是简单的定义了一个惰性函数,并知道,它在什么时候被真正调用,我们之前说过,如果你的项目中用了惰性函数,那么,你就要小心了,为什么呢,我们下面接着看一个例子:
我们这里只针对一个播报员,我们不再让他播报一条新闻,而是播报三条新闻,和上面的一样,我们不知道这三条新闻什么时候会播出,所以,我们仍然使用惰性函数来保留播报新闻这一行为(函数),demo设计如下:
#/usr/bin/env Python3
#-*- encoding:UTF-8 -*-
'''
返回函数,顾名思义,就是一个函数的返回值是一个函数
Java、C#中返回一个函数,是不是听起来怪怪的,好像也不能吧
C/C++可以做到返回函数的指针
但是,像Python这种直接返回函数名的,真是大胆创新啊
'''
def cast(Name):
fL = [] #函数列表(数组)
for s in ['新闻A','新闻B','新闻C']:
def cast_News():
return Name+',开始播报'+s
fL.append(cast_News) #每循环一次,把播报新闻这一行为存到函数列表fL里,
#根据cast_News函数的返回值,我们会以为,第一个播报新闻的行为肯定是针对新闻A的
#-----------------------------------第二个播报新闻的行为肯定是针对新闻B的
#-----------------------------------第三个播报新闻的行为肯定是针对新闻C的
return fL #最后我们返回这个函数列表
#我们针对上面的猜想,我们来验证一下:
for f in cast("appleyk"): #注意,f取出的是一个函数入口地址,如使用,请写完整f()
print(f())
我们看下,Debug结果,是不是我们猜想的:
为了跟踪一下函数的执行情况,我们利用鼠标左键轻轻的打个断点,然后F5开始调试,F7单步执行,当我们循环到第二层播报时,我们发现如下:
我们发现,s确实等于过 '新闻B',那为什么新闻B没有出现在播报里呢,我们继续F7单步执行下去,直到第三层循环(结束):
以上的这种在惰性函数里面声明一个局部变量,然后返回函数使用了这个局部变量,且这个局部变量可能会被多个新返回的函数共用,我们称这种行为叫闭包
官网说法这样说的:
#/usr/bin/env Python3
#-*- encoding:UTF-8 -*-
'''
返回函数,顾名思义,就是一个函数的返回值是一个函数
Java、C#中返回一个函数,是不是听起来怪怪的,好像也不能吧
C/C++可以做到返回函数的指针
但是,像Python这种直接返回函数名的,真是大胆创新啊
'''
def cast(Name):
fL = [] #函数列表(数组)
def news(s): #我们再定义一个惰性函数,返回我们的播报新闻函数,这个函数有个新闻内容参数
def new():
return Name+',开始播报'+s
return new #这里,我们就可以将不同的新闻加进不同的播报行为里,而不会发生同一个新闻被播报N次
for s in ['新闻A','新闻B','新闻C']:
fL.append(news(s)) #这里,我们循环加入播放行为,局部变量s已经作为参数传递出去了
return fL #最后我们返回这个函数列表
#我们看下,这个时候,我们输出的会是什么结果呢?
for f in cast("appleyk"):
print(f())
这个惰性函数,讲起来特别绕,好在,我们有IDE,可以去单步跟踪函数的执行顺序和监控变量值的变化,从而发现端倪,实际上,我们会这样写函数吗?大多数情况下我们不会,但是,既然Python支持这种函数,我们就要去了解一下它,不然,真等我们工作或是学习中遇到了,我们肯定傻眼了。
结束语:
惰性函数告诉我们,它不是真的懒,而是它在等待时机,等一个可以让自己发挥奇效的人出现,也许能等到,也许等不到,总之,它很被动;
我们不要像惰性函数那样,生来就是等待机会的,我们要向高阶函数那样,寻找目标,主动出击,生活才能如沐春风,如鱼得水。