装饰器分步解释-形成过程:
#-*- coding: UTF-8 -*- #示例1: def decop_args): def pack): print'haha,i am deco fun') print'i want to use parent fun arg: '+p_args) print'haha,i am deco fun--finished ') return pack deco'abc') #执行结果无返回值 deco'abc')) #执行结果同示例2 #示例2: def decop_args): def pack): print'haha,i am deco fun') print'i want to use parent fun arg: '+p_args) print'haha,i am deco fun--finished ') return pack) #需要加上小括号,否则pack函数不会被执行 deco'abc') #执行结果返回如下: #haha,i am deco fun #there are 2 args.they are: #haha,i am deco fun--finished #示例3: def myf): print'i want to be decorated.') def decofun): def pack): print'haha,i am deco fun') #print'i want to use parent fun arg: '+p_args) fun) print'haha,i am deco fun--finished ') return pack #此处不加括号,decomyf)执行结果无返回。同示例1 decomyf) #执行结果无返回。 decomyf)) #执行结果同示例4 #示例4: def myf): print'i want to be decorated.') def decofun): def pack): print'haha,i am deco fun') #print'i want to use parent fun arg: '+p_args) fun) print'haha,i am deco fun--finished ') return pack) #加括号,decomyf)执行结果输出如下,同示例2 decomyf) #将myf函数传给deco函数的参数fun。 #haha,i am deco fun #i want to be decorated. #haha,i am deco fun--finished #示例5: def myf): print'i want to be decorated.') def decofun): def pack): print'haha,i am deco fun') #print'i want to use parent fun arg: '+p_args) fun) print'haha,i am deco fun--finished ') return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如decomyf)) #decomyf))的执行结果等价于如下,输出结果同示例4: myf1 = decomyf) myf1) #haha,i am deco fun #i want to be decorated. #haha,i am deco fun--finished #此处的变量myf1跟myf没有任何关系,只是将decomyf)这个函数赋予了变量myf1,然后再通过myf1)的方式执行该函数。所以可以将myf1重新写为myf,就成了装饰器的效果,如示例6。 myf = decomyf) myf) #示例6--装饰器: def decofun): def pack): print'haha,i am deco fun----') #print'i want to use parent fun arg: '+p_args) fun) print'haha,i am deco fun--finished ') return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如decomyf)) @deco def myf): print'i want to be decorated,6.') myf)
装饰器中的函数参数传递:
def decofun): def pack*args,**kwargs): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。 print'haha,i am deco fun') print'there are %d args.they are: %s %d' %lenargs),args[0],args[1])) #调用原函数的参数 fun*args,**kwargs) print'haha,i am deco fun--finished') return pack @deco #将sayhi传给deco的参数fun def sayhiname,age): print'helo,i am %s ,my age is %d.'%name,age)) sayhi'LiuXue',20) #返回结果: haha,i am deco fun there are 2 args.they are: LiuXue 20 helo,i am LiuXue ,my age is 20. haha,i am deco fun--finished
#定义函数: def hello*args,**kw): print 'ab' print args print kw args=range1,5) helloargs) #返回值: ab [1, 2, 3, 4],) {} #定义装饰函数: def decfun): def wrapper*args,**kw): print 'do sth. before' fun*args,**kw) print 'do sth. after' return wrapper dechelloargs)) #将hello函数及参数当做变量赋予dec,只相当于直接执行helloargs),返回值: ab [1, 2, 3, 4],) {} p=dechello) pargs) dechello)args) #将函数当做变量赋予dec,然后通过变量调用函数,再赋予变量变量,返回值: do sth. before ab [1, 2, 3, 4],) {} do sth. after
def decfun): def wrapper*args,**kw): print 'do sth. before' fun*args,**kw) #此处如果改为 return fun*args,**kw),则下一句print 'after'不会再执行。在函数中,遇到第一个return则不会再执行后面的语句,如果返回两个值,可以写在同一行。如果用了return,函数执行完会得到结果,没有return则无返回值 print 'do sth. after' return wrapper @dec #通过@调用装饰函数 def hello*args,**kw): print 'ab' print args print kw args=range1,5) helloargs)
装饰器自身接收参数:
# -*- coding: UTF-8 -*- def decodarg): #装饰函数的参数 print darg def getFunfunc): def packname,age): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。 print'haha,i am darg: '+darg) #装饰函数的参数可以传入使用 print'there are args.they are: %s %d' %name,age)) #调用原函数的参数 funcname,age) print'haha,i am deco fun--finished') return pack return getFun @deco'abc') #装饰函数调用参数‘abc’ def sayhiname,age): m=15 print'helo,i am %s ,my age is %d.'%name,age)) name='LiuXue' age=20 sayhiname,age) # #返回结果: abc haha,i am darg: abc there are args.they are: LiuXue 20 helo,i am LiuXue ,my age is 20. haha,i am deco fun--finished