闭包(函数闭包),引用了自由变量的函数。
这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
简单来说:
一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。
这个返回的函数B就叫做闭包。
你在调用函数A的时候传递的参数就是自由变量。
一个比较有意思的Python返回函数的例子
def count(): fs = [] for i in range(1, 4): def f(j): def g(): return j*j return g r = f(i) fs.append(r) return fs f1, f2, f3 = count() print f1(), f2(), f3()
这里的r是f(i)的返回值,也就是g这个函数
所以fs这个列表里面存放的是g函数的集合
另一个例子:
def count(): def f(): def g(): return 3 return g return f f1 = count() print f1()()
这个count返回的就是f函数,但是f函数返回的还是一个函数,
所以使用f1()这样的方式,就会出现错误
如果f函数的返回值更改为g()的话,那么返回的就是一个数,就可以用f1()的方式
无参数装饰器
def decorator(temp): def f(x): print "Decorator" return temp(x) return f @decorator # 这里@符号后面是一个装饰器的函数名,可以和有参装饰器做对比 def temp(x): return x print temp(3)
这里的实现原理为:
temp = decorator(temp) print temp(3)
将temp函数名作为参数传递给decorator,实际返回的是decorator函数内部的函数,
所以temp虽然名字相同,但是其实是已经改变了,temp虽然是一个函数名,但是也是一个变量,
再使用这个函数,打印出log信息,并调用原本temp函数
有参装饰器
def parameterDecorator(parameter): def decorator(temp): def f(x): print "Decorator" print parameter return temp(x) return f return decorator @parameterDecorator("Debug") # 这里parameterDecorator("Debug")整体也相当于一个函数名 def temp(x): return x print temp(3)
这来的实现原理:
f1 =parameterDecorator("Debug") # 返回一个decorator函数 temp = f1(temp) # 传入temp函数作为参数,返回一个f函数 print temp(3) # 调用f函数内部过程,返回temp函数值
经过装饰器的函数就已经改变了,再使用的时候,即是经过改变的函数
In [2]: def parameterDecorator(parameter): ...: def decorator(temp): ...: def f(x): ...: print "Decorator" ...: print parameter ...: return temp(x) ...: return f ...: return decorator ...: In [3]: @parameterDecorator("Debug") ...: def temp(x): ...: return x; ...: In [4]: print temp(3) Decorator Debug 3 In [5]: f1 = parameterDecorator("HI") In [6]: temp = f1(temp) In [7]: print temp(4) Decorator HI Decorator Debug 4