Python 函数对象与闭包
转载请标明出处(http://blog.csdn.net/lis_12/article/details/52835786).
函数对象
函数在Python中也是对象,也就是说函数也可以当成参数传递给其他函数,放在数据结构中,也可以作为函数的返回值.
当函数当作数据处理时,它将显式地携带与定义该函数的周围环境相关的信息.这将直接影响到函数中自由变量的绑定方式.
#foo.py
x = 1
def callfunc(func):
return func()
#test.py
import foo
x = 2
def hello():
print "hello.py x = %d"%x
foo.callfunc(hello) #hello.py x = 2,hello函数用的是test.py中x的值
闭包
foo.callfunc(hello)中的hello将组成hello()函数的语句与这些语句的变量及其执行环境打包在一起,此时得到的对象称为闭包.
使用嵌套函数时,闭包将捕捉内部函数执行所需的整个环境.
#foo.py x = 1 def callfunc(func): return func() #test.py import foo def bar(): x = 2 def hello(): print "hello.py x = %d"%x foo.callfunc(hello) bar() #hello.py x = 2
编写惰性求值或延迟求值的代码时,闭包和嵌套函数会发挥很大的作用.
def bar(): x = 2 def hello(): print "hello.py x = %d"%x return hello cnt = bar() print cnt #<function hello at 0x00000000035D2828> cnt() #hello.py x = 2
bar()并没有左任何有意义的计算,它只是创建了hello函数,但是并未调用.
如果需要在一系列函数中保持某个状态,使用闭包是一种非常高效的方式.
def fun(): l = [] def add_num(num = 0): l.append(num) return l return add_num n = fun() for i in range(3): v = n(i) print v if len(v) > 10: break ''' result: [0] [0, 1] [0, 1, 2] '''
保留了l的状态.
闭包会捕捉内部函数的环境,因此可以用来包装现有的函数,以便增加函数额外的功能.装饰器就是利用的此特征.
装饰器
(http://blog.csdn.net/lis_12/article/details/52693521)