zoukankan      html  css  js  c++  java
  • 装饰器

    开放封闭原则

    软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的,也就是说我们必须要找到一种解决方案:

      能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能。

    总结

    原则如下:

    1、不修改源代码

    2、不修改调用方式

    目的:

    在遵循1和2原则的基础上扩展新功能

    装饰器:

    器指的是工具,装饰指的是为被装饰对象添加新功能,

    完整含义:

    装饰器即在不修改被装饰对象源代码与调用方式的前提下, 为被装饰器的对象添加新功能。

    装饰器与被装饰的对象均可以是任意可调用的对象

    装饰器=======》函数

    被装饰的对象=========》》函数

    无参装饰器

    import time
    def index():
        star_time =time.time()
        time.sleep(1)
        print('welcome to index page')
        stop_time=time.time()
        print('run time is %s' %(stop_time-star_time))
    
    index()
    
    
    #打印结果为
    
    welcome to index page
    run time is 1.0006649494171143

    修订方案一

    import time
    def index():
        time.sleep(1)
        print('welcome to index page')
    
    def home(name):
        time.sleep(2)
        print('welcome %s to home page '%name)
    
    star_time =time.time()
    index()
    stop_time=time.time()
    print('run time is %s'%(stop_time-star_time))
    
    star_time=time.time()
    home('egon')
    stop_time =time.time()
    print('run time is %s'%(stop_time-star_time))
    
    #打印结果:
    welcome to index page
    run time is 1.0000946521759033
    
    welcome egon to home page 
    run time is 2.0007834434509277
    
    
    #修改方案一   此种方法麻烦, 每增加一个或更改 都要从新写一个代码。比较麻烦, 不推荐
    import time
    def index():
        time.sleep(1)
        print('welcome to index page')
    
    def home(name):
        time.sleep(2)
        print('welcom to home page'%name)
    
    def wrapper(func):
        star_time=time.time()
        func()
        stop_time =time.time()
        print ('run time is %s'%(stop_time-star_time))
    
    wrapper(index)
    

    修改方法二: #对于index( )的调用结果 welcome to index page run time
    is 1.0006787776947021 虽然实现了index()增加新功能作用但是却更改了调用方式改成了 wrapper(index)所以是不可以的 而对于home(name )这种有参函数却无法修改, 所以这种修改方式也是不可以的

    import time def index(): time.sleep(
    3) print('welcom to index page') def outter(func): #func=原index def wrapper(): star_time=time.time() func() #原index 即打印welcom to index page stop_time=time.time() print(stop_time-star_time) # 算时间得结果 return wrapper #返回wrapper函数 index=outter(index) index() #针对index做的修改方案

    无参装饰器升级版

    import time
    def index():
        time.sleep(1)
        print('welcom to index page')
        return 122
    def home(name):
        time.sleep(2)
        print('welcome %s to home page'%name)
    
    def timmer(func):   #func=原index   或者func=原home    所以这个func没有被固定死,可以为其赋不同的值
        def wrapper(*args,**kwargs):
            star_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print(stop_time-star_time)
            return res
        return wrapper
    
    index=timmer(index)
    home=timmer(home)
    
    index()
    home(name='egon')
    
    #打印结果
    
    welcom to index page
    1.0009210109710693
    welcome egon to home page
    2.000316619873047
    
    升级最终版本
    针对这种解决方案  就是用闭包函数 并把之前学过的 *args 与**kwargs  应用到此处 ,完美的解决

    无参装饰器的模板   重点

    def outer(func):
        def inner(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
        return inner

    语法糖

    放在被装饰函数的正上方, 单独一行,修饰简洁 便于程序员理解,

    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            star_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print(stop_time-star_time)
            return res
        return wrapper
    @timmer       #语法糖, 表示index =timmer(index)
    def index():
        time.sleep(1)
        print('welcom to index page')
        return 122
    @timmer        #语法糖  表示 home=timmer(home)
    def home(name):
        time.sleep(2)
        print('welcom %s to home page'%(name))
    
    index()
    home('egon')

    认证装饰器

     

    import time
    current_user={'username':None,
                  }
    def auth(func):
        def wrapper(*args,**kwargs):
            if current_user['username']:
                print('已经登录过了')
                res=func(*args,**kwargs)
                return res
    
            uname =input('用户名:').strip()
            pwd =input('密码:').strip()
            if uname =='egon'and pwd =='123':
                print('登陆成功')
                current_user['username']=uname
                res =func(*args,**kwargs)
                return res
            else:
                print('用户名或密码错误')
        return wrapper
    @auth
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    @auth
    def home(name):
        time.sleep(2)
        print('welcome %s to home page '%(name))
    
    index()
    
    home('egon')

    叠加装饰器

    @timmer # timmer 统计的是auth+index的执行时间
    @auth
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    index()
    
    @auth
    @timmer  # timmer 统计的是index的执行时间
    
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    index()

    有参装置器

    import time
    current_user={
        'username':None,
        # 'login_time':None
    }
    
    def auth(engine):
        # engine='file'
        def auth2(func):
            # func=index
            def wrapper(*args,**kwargs):
                if engine == 'file':
                    if current_user['username']:
                        print('已经登陆过了')
                        res=func(*args,**kwargs)
                        return res
    
                    uname=input('用户名>>: ').strip()
                    pwd=input('密码>>: ').strip()
                    if uname == 'egon' and pwd == '123':
                        print('登陆成功')
                        current_user['username']=uname
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('用户名或密码错误')
                elif engine == 'mysql':
                    print('基于MyQL的认证')
                elif engine == 'ldap':
                    print('基于LDAP的认证')
            return wrapper
        return auth2
    
    @auth('ldap') #@auth2 #index=auth2(index) #index=wrapper
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    
    index() # wrapper()
  • 相关阅读:
    HDU4812 D Tree(树的点分治)
    BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
    HDU4862 Jump(放大边权的费用流)
    SCU3185 Black and white(二分图最大点权独立集)
    HDU3729 I'm Telling the Truth(字典序最大的最大流)
    HDU3586 Information Disturbing(树形DP)
    HDU3657 Game(最小割)
    POJ3162 Walking Race(树形DP+尺取法+单调队列)
    SCU3312 Stockholm Knights(最大流)
    Codeforces 161D Distance in Tree(树的点分治)
  • 原文地址:https://www.cnblogs.com/lx3822/p/8670886.html
Copyright © 2011-2022 走看看