闭包 装饰器

闭包

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

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  阅读(187)  评论(0编辑  收藏  举报

导航