码迷,mamicode.com
首页 > 编程语言 > 详细

python学习笔记-Day05-第一部分(再谈装饰器)(递归)

时间:2015-11-25 01:13:13      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:python   装饰器   递归   

今天又花了多半天来学习装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
@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


本文出自 “Will的笔记” 博客,请务必保留此出处http://timesnotes.blog.51cto.com/1079212/1716574

python学习笔记-Day05-第一部分(再谈装饰器)(递归)

标签:python   装饰器   递归   

原文地址:http://timesnotes.blog.51cto.com/1079212/1716574

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!