今天又花了多半天来学习装X利器---装饰器,

来详细的讲讲装饰器的用法

还是要说一下,学装饰器之前要先搞清楚什么是函数。装饰器就是对函数进行一个包装,打个比喻来说就是:

假设有一个箱子A,在箱子A的外面又套了一个大箱子,外面的大箱子还起名叫A,以后在找里面的小箱子A的时候,就先去找外面的大箱子A,打开外面的大箱子A之后 在打开内部的小箱子A,这个就是装饰器。

  1. 装饰器也是一个函数,至少两层

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@outterdef foo(arg,*args):    print arg,"---",argsfoo(1,2,3,4)

5.多装饰器

一个函数可以被多个函数同时装饰,函数被多个装饰器装饰的时候,效果类似于俄罗斯套娃。

def w1(fun):    def inner():        print "w1,before"        fun()        print "w1,after"    return innerdef w2(fun):    def inner():        print "w2,before"        fun()        print "w2,after"    return  inner@w2@w1def foo():    print "foo"foo()

执行结果

w2,beforew1,beforefoow1,afterw2,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