今天又花了多半天来学习装X利器---装饰器,
来详细的讲讲装饰器的用法
还是要说一下,学装饰器之前要先搞清楚什么是函数。装饰器就是对函数进行一个包装,打个比喻来说就是:
假设有一个箱子A,在箱子A的外面又套了一个大箱子,外面的大箱子还起名叫A,以后在找里面的小箱子A的时候,就先去找外面的大箱子A,打开外面的大箱子A之后 在打开内部的小箱子A,这个就是装饰器。
- 装饰器也是一个函数,至少两层
def outter(func): #定义函数 outter,参数为一个函数的函数名,这里为func, def inner(): #定义函数inner print "before" tmp = func() #执行函数func(), 这里的func为outter的参数 print "after" return tmp return inner # 返回函数名inner @outter # 给下面的函数加装饰器,这里是一个语法糖 def foo(): # 定义函数foo print "foo" foo() #指定函数foo(),这里的 foo() 函数为经过装饰器装饰的函数
输出:
before
foo
after
2. 执行上面代码的时候,被装饰的函数foo()的函数名foo作为参数,即outter(foo); outter函数的返回值,重新赋值给被装饰的函数的函数名
3.装饰器可以装饰有N(N>=0)个参数的函数,对于有不同个数参数的函数来说,装饰器使用动态参数来处理传参的问题,我们修改上面的例子,修改后就解决了传参的问题:
4. 函数的返回值,如果函数有返回值,我们就要考虑函数的返回值如何传递回来,直接将函数的返回结果return就可以了:
def outter(func): def inner(*args,**kwargs): #设置参数 print "before" tmp = func(*args,**kwargs) #设置参数,这里的参数和inner的参数一样 print "after" return tmp # 变量tmp的值为func(*args,**kwargs)的执行结果,返回装饰后函数的返回值 return inner @outter def foo(arg,*args): print arg,"---",args foo(1,2,3,4)
5.多装饰器
一个函数可以被多个函数同时装饰,函数被多个装饰器装饰的时候,效果类似于俄罗斯套娃。
def w1(fun): def inner(): print "w1,before" fun() print "w1,after" return inner def w2(fun): def inner(): print "w2,before" fun() print "w2,after" return inner @w2 @w1 def foo(): print "foo" foo()
执行结果
w2,before w1,before foo w1,after w2,after
6. 带参数的装饰器(至少三层)
就是给函数加装饰器的时候,装饰器还带有参数,代码如下:
def Filter(before_func,after_func): pass @Filter(Before, After) def Index(request,kargs): pass
现在上完整代码,然后解释:
def Before(request,kargs): #1 加载Before函数到内存 #14 执行函数 Before print ‘before‘ #15 执行print语句 def After(request,kargs): #2 加载After到内存 #21 执行After函数 print ‘after‘ #22 执行print语句 def Filter(before_func,after_func): #3 加载函数Filter到内存 #5 执行装饰器Filter def outer(main_func): #6 加载函数outer到内存 #8 执行函数outer def wrapper(request,kargs): #9 加载函数wrapper #12 执行函数wrapper before_result = before_func(request,kargs) #13 给before_result赋值 if(before_result != None): # 16 执行if语句,这里判断为假 return before_result main_result = main_func(request,kargs) #17 给变量main_result赋值 if(main_result != None): #19 执行if语句,这里判断为假 return main_result after_result = after_func(request,kargs) #20 给after_result赋值 if(after_result != None): #23 执行if语句, 这里判断为假 return after_result return wrapper #10 返回函数outer的返回值,warapper return outer #7 返回Filter函数的返回值,即函数名outer @Filter(Before, After) #4 发现装饰器Filter, #17 执行Filter(Before, After) def Index(request,kargs): print ‘index‘ #18 执行print语句 Index("quest0","kwargs0") #11 执行函数 Index
###############################################################
递归
递归算法是一种 直接或间接的调用自身的一种算法。
打个比喻来说就向下面这样
从前有座山,山上有座庙,庙里有个老和尚,老和尚对小和尚说:从前有座山,山上有座庙,庙里有个老和尚,老和尚对小和尚说:从前有座山,山上有座庙,庙里有个老和尚,老和尚对小和尚说。。。。。。。。
递归算法可以有效的解决一大类问题,比如经典的 汉诺塔(又称河内塔)问题,
递归算法的特点是
1. 在函数或者过程里调用自身
2. 必须有一个明确的条件,可以让递归结束
3. 算法简洁,但是效率低
4. 容易造成栈溢出(因为在执行过程中,每一层的返回点、局部变量等都要开辟栈来存储)
以实现斐波那契数列为例:
def fib(a1,a2): # print a1,a2, a3=a1+a2 if a3>100: #这里加入了结束条件,如果没有这个条件,会形成死循环 return a3 # print a3, return fib(a2,a3) # fib(a2,a3) print fib(0,1)
递归是可以和while互相转换的。
上面的代码用while循环来实现的的代码是:
a1,a2 = 0,1
while a1<200:
print a1
a2=a1+a2
a1=a2-a1
http://timesnotes.blog.51cto.com/1079212/1716574
http://www.timesnotes.com/?p=114