zoukankan      html  css  js  c++  java
  • Python学习札记(二十四) 函数式编程5 返回函数

    参考:返回函数

    NOTE

    1.高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

    eg.求和函数

    #!/usr/bin/env python3
    
    def calsums(*args):
    	ans = 0
    	for i in args:
    		ans = ans+i
    	return ans
    
    def slowcalsums(*args):
    	def cal():
    		ans = 0
    		for i in args:
    			ans = ans+i
    		return ans
    	return cal
    
    def main():
    	resf = slowcalsums(1, 2, 3, 4, 5)
    	print(resf)
    	print(resf())
    
    if __name__ == '__main__':
    	main()
    
    sh-3.2# ./func1.py 
    <function slowcalsums.<locals>.cal at 0x1013dab70>
    15
    

    可以看到slowcalsums函数返回的是一个函数,赋值给resf之后resf指向该函数,调用resf()得到计算结果。

    2.上例中,在函数slowcalsums中定义了函数cal,并且,内部函数cal可以引用外部函数的参数和局部变量,当slowcalsums返回函数cal时,相关参数和变量都保存在返回的函数中。这种称为“闭包(Closure)”的程序结构拥有极大的威力。

    3.注意,每一次调用返回函数的函数时,返回的函数都是新的函数:

    newresf = slowcalsums(1, 2, 3, 4, 5)
    	if resf == newresf :
    		print('Yeah')
    	else :
    		print('Noop')
    
    Noop
    

    resf()与newresf()的调用结果互不影响。

    4.Closure。

    (1)注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。

    (2)注意,返回的函数没有立即执行,而是直到调用了f()才执行。

    #!/usr/bin/env python
    
    def count():
    	ans = []
    	for i in range(1, 4):
    		def f():
    			return i*i
                    # 往ans中插入未执行的f(),相当于保存算法,此时i一直在变,当最后调用时,i=3.
    		ans.append(f) 
    	return ans
    
    def main():
    	f1, f2, f3 = count() # 返回的是由函数组成的list
    	print(f1())
    	print(f2())
    	print(f3())
    
    if __name__ == '__main__':
    	main()
    

    你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

    sh-3.2# ./func2.py 
    9
    9
    9
    

    因为变量i在第一个函数调用结束之后值为3.在f2和f3调用的时候值停留于3,于是结果均为9。

    ps.无力吐槽的代码,为了说明而说明。

    但是这样写的话,就不一样了:

    def count1():
    	ans = []
    	def f():
    		for i in xrange(1, 4):
    			ans.append(i)
    		return ans
    	return f
    
    def main():
    	a1, a2, a3 = count1(), count1(), count1()
    	print(a1())
    	print(a2())
    	print(a3())
    
    [1, 2, 3]
    [1, 2, 3]
    [1, 2, 3]
    

    返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

    返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

    2017/2/17

  • 相关阅读:
    在Android中,使用Kotlin的 API请求简易方法
    Android开发者的Kotlin:书
    用Kotlin开发Android应用(IV):定制视图和Android扩展
    用Kotlin开发Android应用(III):扩展函数和默认值
    zookeeper应用
    BigDecimal的setScale()方法无效(坑)
    Linux命令详解之—less命令
    jdk10 var定义变量的由来
    Mysql DataPacketTooBigException异常处理
    JDK自带的监控工具方法
  • 原文地址:https://www.cnblogs.com/qq952693358/p/6411406.html
Copyright © 2011-2022 走看看