闭包 装饰器
闭包
我们先用一个例子来理解闭包:
def fun1():
a, b, c = 1, 2, 3
def fun2():
x = 100
print "outer var a is ", a
print "inner var x is", x
return fun2
f = fun1()
f()
上述代码,运行f()输出如下:
outer var a is 1
inner var x is 100
虽然f 是 fun1的返回,按理说就是fun2。 但实际上又不是fun2. 它是fun2和变量a的一个集合。我们这里称其为闭包。 闭包的定义如下:
嵌套定义在非全局作用域中的函数,当它的外部函数被调用就会生成一个闭包,闭包中包含了这个子函数本身的代码与其依赖的外部变量的引用
装饰器就是通过闭包来实现的。
普通装饰器
def outter(function):
def wrapper():
print "do something before call func"
result = function()
print "do something after call func"
return result
return wrapper
def hello():
print "hello"
hello = outter(hello)
hello()
这里的wrapper调用了其外部的function。在outter(hello) 返回后,返回的其实不是wrapper,而是wrapper和hello的一个集合。 这就是python装饰器的原理。不过python加了一些语法糖,所以真正写装饰圈的时候语法如下:
@outter
def hello():
...
它相当于 hello = outter(hello)
带参数的装饰器
没有参数的装饰器如下
@outter
def hello():
...
有参数的就应该是
@outter(*args, **kwargs)
def hello():
...
它相当于 hello = outter(*args, **kwargs)(hello) 也就是说,我们让outter再返回一个装饰器即可,比如:
def outter(*args, **kwargs):
def outter1(func):
print "*args or decorator ", args
print "**kwargs of decorator ", kwargs
def wrapper():
print "do something before call func"
result = func()
print "do something after call func"
return result
return wrapper
return outter1
@outter('arg1','arg2','arg3', kw1='kw1',kw2='kw2')
def hello():
print "hello"
hello()
运行如下:
*args or decorator ('arg1', 'arg2', 'arg3')
**kwargs of decorator {'kw1': 'kw1', 'kw2': 'kw2'}
do something before call func
hello
do something after call func