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

    一:开放封闭原则

    对修改源代码是封闭的,对功能的扩展是开放的。软件一旦上线后,就应该遵循开放封闭原则。即对修改源代码是封闭的,对功能源代码以及调用方式的前提下,为其加上新功能。

    总结:

    1.不修改源代码

    2.不修改调用方式

    目的:

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

    二:装饰器

    什么是装饰器?

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

    完整含义:

    装饰器即在不修改被装饰对象源代码与调用的前提下,装饰器与被装饰的对象均可以任意可调用的对象。

    装饰器----》函数

    被装饰器---》函数

    三:装饰器的使用

    1.无参函数

    import time
    def index():
        time.sleep(2)
        print('welcome to index page')
    def outter(fund):
        def wrapper():
            start_time=time.time()
            fun()
            stop_time=time.time()
            print('stop_time-start_time')
        return wrapper.  (这里函数wrapper不能加括号,加了括号返回值就是None)
    index=index(index) (index=wrapper,一个新的index)
    index()       ( 相当于wrapper() )

    无参函数升级版

    import time
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    def home(name):
        time.sleep(2)
        print('welcome %s to home page'%name)
    
    def timmer(func)
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)#调用最原始的home
            stop_time=time.time()
            print(stop_time-start_time)
            return res
         return wrapper
    index
    =timmer(index) (#新的index=wrapper) home=timmer(home)    (#新的home=wrapper) home(name='egon')   (#新的wrapper=‘name’) index()         (#新的wrapper())

    装饰器语法糖

    注意点:

    @这个符号相当于承上启下的意思

    举例:@timmer  timmer这个函数必须上面有,而下面如果是接的函数是index,那么就可以表示为index=timmer(index)。如果下面接的是 home,那就表示为home=timmer(home)

    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print(stop_time-start_time)
            return res
        return wrapper
    
    @timmer       #index=timmer(index)(). (相当于index=wrapper(index)) 
    def index():
        time.sleep(1)
        print('welcome to index page')
        return 122
    
    @timmer        #home=timer(home)()。(相当于home=wrapper(home)
    def home(name):
        time.sleep(2)
        print('welcome %s to home page'%name)
    
    home('egon')
    index()
     

    认证装饰器实现

    import time
    current_user={
        'username':None,
        # 'login_time':None
    }
    
    def auth(func):
        # func=index
        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 #index=auth(index)( )
    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')

    叠加多个装饰器

    import time
    current_user={
        'username':None,
        # 'login_time':None
    }
    
    def auth(func):
        # func=index
        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
    
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print(stop_time-start_time)
            return res
        return wrapper
    
    @timmer # timmer 统计的是auth+index的执行时间
    @auth
    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()
  • 相关阅读:
    天气渐凉,意渐浓
    WebBrowser 多线程 DocumentCompleted 和定时器
    浅谈 Glide
    浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap
    XGoServer 一个基础性、模块完整且安全可靠的服务端框架
    GreenDao 兼容升级,保留旧数据的---全方面解决方案
    基于 xorm 的服务端框架 XGoServer
    全面总结: Golang 调用 C/C++,例子式教程
    通俗易懂,各常用线程池的执行 流程图
    为什么我的子线程更新了 UI 没报错?借此,纠正一些Android 程序员的一个知识误区
  • 原文地址:https://www.cnblogs.com/wuchenyu/p/8670915.html
Copyright © 2011-2022 走看看