Python中为什么要使用函数嵌套函数?
看一些代码会写成函数中嵌套函数,例如:
def func():
def new_func():
return 1
a = new_func()
这种写法和 lambda 和单独创建一个 function 有什么区别或优势吗?
Python中为什么要使用函数嵌套函数?
嵌套函数在Python里挺常见的,主要就几个实在的用处。
1. 封装与隐藏实现细节 最直接的就是把只在外部函数里用到的逻辑包起来,不污染全局命名空间。比如做个计数器生成器:
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
c = make_counter()
print(c()) # 1
print(c()) # 2
这里的counter函数和count变量在外面都访问不到,干净。
2. 利用闭包保存状态 就像上面例子,内部函数能“记住”外部函数的局部变量(形成闭包),比用类写起来更轻量。
3. 实现装饰器 这是嵌套函数最典型的应用场景了。装饰器本质上就是个返回内部函数的高阶函数:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("函数执行前")
result = func(*args, **kwargs)
print("函数执行后")
return result
return wrapper
4. 辅助函数与代码组织 在一个复杂的函数里,把一部分逻辑拆成内部函数,能让主流程更清晰,而且这个辅助函数只在这里有用,没必要放外面。
5. 工厂模式与定制行为 外部函数通过参数来定制不同的内部函数并返回,比如:
def power_factory(exponent):
def power(base):
return base ** exponent
return power
square = power_factory(2)
cube = power_factory(3)
print(square(5)) # 25
print(cube(3)) # 27
简单说: 需要隐藏数据、保存状态、写装饰器或者整理代码结构时,嵌套函数就很顺手。
对啊,要写闭包的时候很好用的
查看一下柯里化的定义,这样写返回的新函数能够保持当时的状态,而且能够达到惰性求值的效果(用到这个函数的时候再处理传入的参数)
例如装饰器传参,就是多层嵌套的函数,
因为 lambda 的限制
你的例子确实 lambda 也可以做到。但是下面的呢?
def func(x):
def new_func(y):
return x+y
return new_func
>>> a = func(10)
>>> a(3)
13
>>> a(5)
15
也许是为了方便吧。脚本嘛
额,其实我也不是很了解这两种用法的差异的,不过一不小心就写了出来
In [1]: def func(x):
…: return lambda y:y+x
…:
In [2]: a = func(10)
In [3]: a(3)
Out[3]: 13
In [4]: a(5)
Out[4]: 15
你的例子不合适啊。
>>> a = lambda x: lambda y: x + y
>>> b = a(10)
>>> b(3)
13
>>> b(5)
15
因为 lambda 是匿名的,我想区别应该是名字是否有意义,比如递归吧。
>>> def func(x, sum):
… if(x==0):
… return sum
… return func(x-1, sum + x)
…
>>> func(10, 0)
55
lambda 大概写不出上面这个递归?
能省几个参数,函数的作用域小了
一般是返回一个函数指针时用。一般外部固定了函数指针的参数,但是自己又需要传递给函数指针一些数据,这样嵌套函数可以使得内部函数可以访问外部函数的变量。关键字:闭包,需求的例子:装饰器。
不用 lambda 的原因是 lambda 限制太大,不方便。
这就是 meta 编程啊
lambda 你能多写几行么
Python 里 lambda 只能写一行啊
需要做到这个的话直接用指针不行吗?
无法实现,像下面的装饰器例子:
https://gist.github.com/GameXG/ed84b114067fb4a7b398cb811a9241ca
需要将 (123) 的 123 传递给 fffff 函数,但是 fffff 函数是会被当作 hello3 参数给用户调用的,用户不会帮你把 123 传递进去,只能通过闭包的方式传递进去 123 .
lambda 写复杂的函数很麻烦啊
这是一种嵌套函数的写法,有时候它和 lambda 没什么区别,但有些情况下它会实现一个闭包,所以我姑且认为楼主是想知道闭包的特性.
那么这里首先强烈建议楼主了解一下 namespace 与变量作用域的相关知识.
http://python.jobbole.com/81367/
如果只要了解闭包的概念,请参考这篇文章.
http://blog.csdn.net/marty_fu/article/details/7679297
如果想知道闭包的实现原理.那么你必须得明白函数调用过程.因为闭包本身就是调用一个函数反回另一个函数.
这里推荐 UCSB 的教程,提供了一个交互式的函数调用演示程序.共6个课程,每个课程都很短,但看完这些你大概能对函数调用帧栈有初步了解.
https://www.cs.ucsb.edu/~pconrad/cs8/topics.beta/theStack/01/
到现在你已经可以开始探究 python 在函数调用中如何精妙地完成参数传递.
http://www.jianshu.com/p/d00108741a18
如果能坚持到这里,那么你已经停不下来了…函数调用过程中所有涉及到的源码作者都给出了分析,看完之后应该什么都明白了
http://python.jobbole.com/83545/
以下链接可以看看,也许能帮助你理解源码.
http://www.cnblogs.com/hackerl/p/5985102.html
http://eli.thegreenplace.net/2012/03/23/python-internals-how-callables-work/
一种劣习,让函数变成有状态的,或者叫不完全依赖于字面输入,还依赖一个隐藏输入的东西
我用这个是因为 有时候要用递归,把 helper 放函数里面可以把外面函数的变量当全局变量。
另外就是 helper 只用这里会用,写外面不清晰。

