zoukankan      html  css  js  c++  java
  • 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删除变量后,内存发现没有变量指向该值,该值也将被删除。

    函数就是一种变量。

  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/iexperience/p/9041608.html
Copyright © 2011-2022 走看看