关于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)了。