闭包 装饰器

闭包

我们先用一个例子来理解闭包:

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

posted on 2017-04-25 17:43  kramer  阅读(213)  评论(0)    收藏  举报

导航