• python 装饰器


    实现装饰器知识储

     1.函数即‘变量'

    2.高阶函数

            (1)把一个函数名当做实参传给另外一个函数   

    def bar(x,y,f):
        print f(x)+f(y)
    bar(-1,-2,abs)
    >>3   
    def bar():
        print '1111'
    print bar  #输出内存地址
    fun=bar    #fun/bar指向内存中的同一地方
    fun()
    
    >><function bar at 0x02249C30>  
    >>1111          

    import time
    def bar():
    time.sleep(3)
    print '1111'
    def f(fun):
    start_time=time.time()
    fun()
    stop_time=time.time()
    print '使用时间%s'%(stop_time-start_time)
    f(bar)
    
    >>1111
    
    >>使用时间3.0  

    (2)返回值中包含函数名

       3.嵌套函数

    def foo():
        print '1111'
        def bar():   #bar相当于局部变量,指定在定义域内调用,不能在外面调用
            print '2222'
        bar()
    foo()
    >>1111
    >>2222
    

      

    x=0
    def g():
        def dad():
            x=2
            def son():
                x=3
                print x
              
            son()
        dad() 
    g()        
    >>3
    

      

    高阶函数+嵌套函数=装饰器

    import time
    def f(fun):
        def g():
            start_time=time.time()
            fun()   #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序!
            print 'fun%s'%fun
            stop_time=time.time()
            print '时长%s'%(start_time-stop_time)
        print 'g%s'%g
        return g    
    @f      #test1=f(test1) #为test1添加装饰器
    def test1():  #函数只有在被调用的时候才被定义(开辟内存空间)。
        time.sleep(3)
        print '11111' 
    print 'test1%s'%test1 
    test1()     #这里的test1指向的是g函数存放的地址(位置)
    >>g<function g at 0x023081F0>
    >>test1<function g at 0x023081F0>
    >>11111
    >>fun<function test1 at 0x02308170>
    >>时长-3.0
    
    import time        可传参数的装饰器
    name=2
    def f(fun):
        def g(s):
            start_time=time.time()
            fun(s)   #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序!
            print 'fun%s'%fun
            stop_time=time.time()
            print '时长%s'%(start_time-stop_time)
        print 'g%s'%g
        return g    
    @f      #test1=f(test1)
    def test1(name):  #函数在内存中被定义,调用该函数时,会开辟一个栈空间,来运行。
        time.sleep(3)
        print '11111' 
    print 'test1%s'%test1 
    test1('hh')     #这里的test1指向的是g函数存放的地址(位置)
    >>g<function g at 0x034C8D30>
    >>test1<function g at 0x034C8D30>
    >>11111
    >>fun<function test1 at 0x02A809B0>
    >>时长-130.470999956   
    import time        通用(无论有无参数)装饰器
    name=2
    def f(fun):
        def g(*a,**b):
            start_time=time.time()
            fun(*a,**b)   #这里的fun指向的是test1最初在内存中的地址,注意整个程序执行的顺序!
            print 'fun%s'%fun
            stop_time=time.time()
            print '时长%s'%(start_time-stop_time)
        print 'g%s'%g
        return g    
    @f      #test1=f(test1)
    def test1(name,age):  #函数在内存中被定义,调用该函数时,会开辟一个栈空间,来运行。
    time.sleep(3) print '11111' print 'test1%s'%test1 test1('hh',23) #这里的test1指向的是g函数存放的地址(位置)
    
    >>g<function g at 0x022281F0>
    >>test1<function g at 0x022281F0>
    >>11111 
    >>fun<function test1 at 0x02228170> 
    >>时长-3.00100016594

    关于函数的命名空间如下:

    当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。 
    等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。 

    具体见:https://blog.csdn.net/qd_ltf/article/details/79698474

    装饰器终极实例:

    通过装饰器实现用户登录接口

    name,pas='xx','qaz123'         #被装饰函数有返回值的实例,需要返回调用函数的值f给所在定义函数调用时的输出print里
    def f(fun):
        def g(*a,**b):
           user_name=raw_input('username:').strip()
           user_pass=raw_input('userpass:').strip()
           if name==user_name and pas==user_pass:
               print '输入正确!'
               f=fun('1','2') #fun函数在定义g函数里面调用,'1','2'传给def home(n,m)里面。
    return f else: print '用户名或密码错误' return g @f def home(n,m): print 'welcome to home page' return n print home(1,2) #这里的home指向的是g函数所在的内存地址,这里面的实参传给def g(*a,**b)里面的形参。 >>username:xx >>userpass:qaz123 >>输入正确! >>welcome to home page >>1
    name,pas='xx','qaz123'    #细化上一实例,实现不同用户或不同页面的登陆(方式)
    def f(t):
        print '%s进入f'%t
        def  k(fun):
            def g(*a,**b):
                if t=='xiaohong':
                   user_name=raw_input('username:').strip()
                   user_pass=raw_input('userpass:').strip()
                   if name==user_name and pas==user_pass:
                       print '输入正确!'
                       f=fun('1','2') #fun函数在定义g函数里面调用,'1','2'传给def home(n,m)里面。
                       return 'xh正确'   #每一个判断条件里面写return是因为,需要返回给当前定义函数的调用位置上。
                   else:
                        print '用户名或密码错误'
                        return 'xiaohong输入错误'
                elif t=='xiaoming':      #if...elif.. if后面为true是将不再判断elif
                    print 'xiaoming不会..'
                    return 'xm走完'
            return g
        return k
    @f(t='xiaohong')
    def updat(n,m):
        print 'welcome to home page'
        return n
    @f(t='xiaoming')
    def home(n,m):
        print 'welcome to home page'
        return n
    print updat(1,2)
    print home(1,2)  #这里的home指向的是g函数所在的内存地址,这里面的实参传给def g(*a,**b)里面的形参。
    
    
    >>xiaohong进入f
    >>xiaoming进入f
    >>username:xx
    >>userpass:qaz123
    >>用户名或密码错误
    >>xiaohong输入错误
    >>xiaoming不会..
    >>xm走完
    

    python 装饰器:

    定义:本质是函数(装饰其他函数)就是为其他函数添加附加功能。

    原则:1.不能修改被装饰的函数的源代码。

               2.不能修改被装饰的函数的调用方式。

    del 删除变量,删除的是内存中的门牌号(变量名),不是变量指向的值,del删除变量后,内存发现没有变量指向该值,该值也将被删除。

    函数就是一种变量。

  • 相关阅读:
    设计模式之Builder (创建者模式)的一些个人理解(转)
    SystemClock.sleep和Thread.sleep的区别(转)
    Android应用开发基础之四:网络编程(一)
    handler机制的原理(转)
    NullPointerException at android.widget.AbsListView.obtainView at android.widget.ListView.makeAndAddView
    Android之Adapter用法总结(转)
    [Done]ibatis/mybatis: java.lang.NoSuchMethodException
    [Done]java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    [Done]FindBugs: boxing/unboxing to parse a primitive
    Python中的基本运算符
  • 原文地址:https://www.cnblogs.com/iexperience/p/9041608.html
Copyright © 2020-2023  润新知