[Python3] 036 函数式编程 返回函数

函数式编程 之

返回函数

  • 函数可以返回具体的值
  • 也可以返回一个函数作为结果

1. 引子

1.1 定义一个普通函数

>>> def func():
...   print("abc")
...   return None
...
>>> my_func = func()
abc
>>> print(my_func)
None
>>> my_func
>>> 

1.2 函数作为返回值返回

  • 被返回的函数在函数体内定义
In [1]: def out_func():
   ...:     def in_func():
   ...:         print("in func")
   ...:         return 100
   ...:     return in_func
   ...:
   ...:

In [2]: f = out_func()

In [3]: print(type(f))
<class 'function'>

In [4]: print(f)
<function out_func.<locals>.in_func at 0x000001B9B99D6BF8>

In [5]: f()
in func
Out[5]: 100

In [6]: 

1.3 带参数列表的返回函数

>>> def out_func(*args):
...   def in_func():
...     rst = 0
...     for i in args:
...       rst += i
...     return rst
...   return in_func
...
>>> f1 = out_func(1, 2, 3, 4, 5)
>>> f1()
15
>>> f2 = out_func(6, 7, 8, 9, 10)
>>> f2()
40


2. 闭包 closure

  • 当一个函数在内部定义函数,并且内部函数应用外部函数的参数或者局部变量时,内部函数被当做返回值之时,相关参数和变量会保存在返回的函数中,这种结果,叫闭包
  • 上方 1.3 带参数列表的返回函数 的例子就是一个标准闭包结构

2.1 常见的关于闭包的坑

>>> def out_func():
...   res = []
...   for i in range(1, 4):
...     def in_func():
...       return i * i
...     res.append(in_func)
...   return res
...
>>> f1, f2, f3 = out_func()
>>> f1()
9
>>> f2()
9
>>> f3()
9
>>> 

2.2 造成上述状况的原因

  • 返回函数引用了变量 ii 并非立即执行,而是等到三个函数都返回的时候才统一使用,此时 i 已经变成了 3,最终调用的时候,返回的都是 3*3

  • 由此可见:返回闭包时,返回函数不能引用任何循环变量

2.3 解决方案

  • 再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不再改变
>>> def out_func():
...   def in1(n):
...     def in2():
...       return n * n
...     return in2
...   res = []
...   for i in range(1, 4):
...     res.append(in1(i))
...   return res
...
>>> f1, f2, f3 = out_func()
>>> f1()
1
>>> f2()
4
>>> f3()
9
>>> 

猜你喜欢

转载自www.cnblogs.com/yorkyu/p/12074849.html