关于netsted function


                                                                用户很广泛的decorator 一般都是用nested function来定义的。
关于nested function下面是一段验证代码
>>> def a():
...     b=[]
...     def c():
...             b.append('s')
...             print b
...     return c
...
>>> a()()
['s']
>>> a()() #**************
['s']
>>> b=a()
>>> b()
['s']
>>> b()   #**************
['s', 's']
>>>
比较上面的#****注释的代码产生的结果,细细体会其中的原因,PEP 227(statically nested scope)讨论的问题与此处有点关系。
再看下面一段代码
>>> def a(pa):
...     lists=[]
...     def b(pb):            
...             def c(pc):
...                     lists.append(pc)
...                     print lists
...             lists.append(pb)
...             print lists
...             return c
...     lists.append(pa)
...     print lists
...     return b
...
>>> a(['pa'])(['pb'])(['pc'])
[['pa']]
[['pa'], ['pb']]
[['pa'], ['pb'], ['pc']]
>>> a(['pa'])(['pb'])(['pc'])
[['pa']]
[['pa'], ['pb']]
[['pa'], ['pb'], ['pc']]
下面是PEP 318(decorator)中的一段decorator的example
def accepts(*types):
    def check_accepts(f):
        assert len(types) == f.func_code.co_argcount
        def new_f(*args, **kwds):
            for (a, t) in zip(args, types):
                assert isinstance(a, t), \
                       "arg %r does not match %s" % (a,t)
            return f(*args, **kwds)
        new_f.func_name = f.func_name
        return new_f
    return check_accepts
def returns(rtype):
    def check_returns(f):
        def new_f(*args, **kwds):
            result = f(*args, **kwds)
            assert isinstance(result, rtype), \
                   "return value %r does not match %s" % (result,rtype)
            return result
        new_f.func_name = f.func_name
        return new_f
    return check_returns
@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
    return arg1 * arg2
注:
(1)decorator函数必须要带一个用来绑定function object的参数,
(2)在decorate函数的时候,可以带一层参数.带参数与不带参数的形式分别等效于new_fun=decorator(f), new_fun=decorator(param)(f)但是不能带多层参数,像 def @decorator(param1)(param2) func(arg1)的形式是非法的。
(3)在上面的例子中,return函数的参数用来绑定decorate时提供的参数(int,float),check_returns函数的参数用来绑定func函数对象,new_f函数则为decorate后的新函数对象,在调用此函数对象时,它的参数就用来绑定(arg1,arg2)了。