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

    一.什么是装饰器

    器指的是工具,而程序中的函数就具备某一功能的工具

    装饰指的是为被装饰器对象添加额外功能

    就目前的知识来看:
    定义装饰器就是定义一个函数,只不过该函数的功能是用来为
    其他函数添加额外的功能

    其实:
    装饰器本身其实可以是任意可调用的对象
    被装饰的对象也可以是任意可调用的对象

    二.为什么要用装饰器

    软件的维护应该遵循开放封闭原则
    开放封闭原则指的是:
    软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的
    这就用到了装饰器

    装饰器的实现必须遵循两大原则:
    1、不修改被装饰对象的源代码
    2、不修改被装饰对象的调用方式
    装饰器其实就在遵循1和2原则的前提下为被装饰对象添加新功能

    三.如何使用装饰器

    无参装饰器:

    计算函数运行时间
    import
    time def index(): start=time.time() print('welcom to index') time.sleep(3) stop=time.time() print('run time is %s' %(stop-start)) index()
    import time
    def index():
        print('welcome to index')
        time.sleep(3)
    
    def f2():
        print('from f2')
        time.sleep(2)
    
    start=time.time()
    index()
    stop=time.time()
    print('run time is %s'%(stop-start))
    start=time.time()
    f2()
    stop=time.time()
    print('run time is %s'%(stop-start))

    装饰器修正:

    import rime        #时间模块
    def timmer(func)
    def wrapper(*args,**kwargs): #什么都能接收,也可以不传值 start=time.time() #计算开始时间 func(*args,**kwargs) stop=time.time() #计算结束时间 print('run time is %s'%(stop-start)) #输出所用时间 return wrapper #返回wrapper的内存地址 def index(): #定义一个名为index的函数 print('welcome to index') #执行时打印welcome to index time.sleep(3) #等待三秒钟 return 123 #返回值为123 可以没有 index=timmer(index) index()

    #这样就不会修改被装饰对象的源代码和调用方式
    基本格式
    def deco(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
        return wrapper

    有参装饰器:

    import time
    current_user={'user':None}
    def auth(engine='file'):
        def deco(func):
            def wrapper(*args,**kwargs):
                if current_user['user']:
                    #已经登陆过
                    res = func(*args, **kwargs)
                    return res
                user=input('username>>: ').strip()
                pwd=input('password>>: ').strip()
                if engine == 'file':
                    # 基于文件的认证
                    if user == 'egon' and pwd == '123':
                        print('login successful')
                        # 记录用户登陆状态
                        current_user['user']=user
                        res=func(*args,**kwargs)
                        return res
                    else:
                        print('user or password error')
                elif engine == 'mysql':
                    print('基于mysql的认证')
                elif engine == 'ldap':
                    print('基于ldap的认证')
                else:
                    print('无法识别认证来源')
            return wrapper
        return deco
    
    @auth(engine='mysql') # @deco #index=deco(index) #index=wrapper
    def index():
        print('welcome to index page')
        time.sleep(1)
    
    @auth(engine='mysql')
    def home(name):
        print('welecome %s to home page' %name)
        time.sleep(0.5)
    
    
    index()
    home('egon')
  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/chillwave/p/9174650.html
Copyright © 2011-2022 走看看