• 装饰器的编写及使用


    装饰器的编写及使用

    返回首页

      装饰器的开放封闭原则:源代码在线上尽量避免更改,也尽量避免调用方式的更改。

      装饰器的本质是在不改变源代码的前提下,添加新的功能。使其原有的类和函数得以增加新的功能。

    import time
    def timmer(func):
        def wrapper(*args,**kwargs):
            print(func)
            start = time.time()
            res = func(*args,**kwargs)
            end = time.time()
            print("run time is %s " %(end - start))
        return wrapper
    
    @timmer   # index = timmer(index) 这就是装饰器,没有改变index函数的代码,但是在运行index函数时,却有了运行时间。
    def index():
        print("welcome to world !!! ")
    
    index() #这个执行的index并不是原始的index函数,而是timmer里的wrapper函数

      @timmer做的事情是:将@timmer下的那个函数作为参数,传给timmer。也就是timmer(index),然后把返回值赋值给index。

      index = timmer(index),这里的返回值是timmer里的wrapper,也就是将wrapper赋值给index。所以执行index() 就是在执行wrapper()。

      执行wrapper(),打印func。这个func就是一开始最原始的index的内存地址。也就是@timmer下面的那个index函数。

      无参装饰器的使用实例:用*args,**kwargs去处理传给wrapper的参数。

    import time
    
    def timmer(func):
        """
        计算代码的运行时间。
        :param args:
        :param kwargs:
        :return: 时间差
        """
        def wrapper(*args,**kwargs):
            print(func)  # 打印的func是index的内存地址。
            #func函数被扩展前的调用代码
            start_time = time.time()
            # 被修饰的函数
            res = func(*args,**kwargs)
            #func函数别扩展后的代码
            end_time = time.time()
            print("run time is %s " %(end_time-start_time))
            return res
        return wrapper
    
    @timmer    # @timmer实际上是 index = timmer(index)
    def index(*args,**kwargs):
        time.sleep(0.3)
        print("index")
    
    @timmer
    def home(name):
        time.sleep(0.2)
        print("home is %s " %(name))
    
    @timmer
    def auth(name,password):
        """
        认证
        :return:
        """
        print("auth:",name,password)
    
    @timmer
    def my_max(x,y):
        print("my_max function")
        res = x if x>y else y
        return res
    
    res = my_max(1,22)    # res = my_max(1,22)  就是在res = warpper(1,22)
    print("===",res)
    
    auth("wang","111")
    home("George")
    index()    #index() 实际上是在执行inner

      无参装饰器的最终版本:可以装饰任何函数的装饰器,其装饰器wrapper的参数是*args和**kwargs。 

    def timmer(func):
        """
        计算代码的运行时间的时间装饰器。
        :param args:
        :param kwargs:
        :return: 时间差
        """
        def wrapper(*args,**kwargs): #wrapper的参数是*,**。这样就可以接收任何不同的数据。
            print(func)  # 打印的func是index的内存地址。
            #func函数被扩展前的调用代码
            start_time = time.time()
            #被修饰的函数
            res = func(*args,**kwargs)
            #func函数别扩展后的代码
            end_time = time.time()
            print("run time is %s " %(end_time-start_time))
            return res
        return wrapper

      有参装饰器:就是给装饰器函数加参数。

      给函数加用户认证功能,是加在真是的函数被调用之前,在函数被调用之前做用户认证。  

    def auth(auth_type):
        """
        参数装饰器
        :param auth_type:
        :return:
        """
        def wapper(func):
            """
            认证功能装饰器
            :param func:
            :return:
            """
            print("AUTH",auth_type)
            def inner(*args,**kwargs):
                if auth_type == "file":
                    print("func the function", func)
                    name = input("username >>:")  #加认证,这个位置是真正实现认证功能的位置
                    password = input("password >>:")
                    if name == "wang" and password == "111":
                        print("ok successfull")
                        res = func(*args,**kwargs)   #被附加装饰器执行的函数
                        return res
                    else:
                        print("error NO")
                elif auth_type == "SQL":
                    print("MySQL,NB大了")
            return inner
        return wapper
    
    @auth(auth_type = "SQL")   #有参数了 将原有的wapper在嵌套进一层,把auth_type搞成参数
    def index():
        print("welcome to index !!!1")
        print("有参数了。不要脸了")
    
    index()

      作业:把用户的登录信息结构化的存入到文件里,在结构化的读出来。实现用户的认证功能。

        不完整版:

    import time
    current_login={'name':None,'login':False}  #加一个标识,用户名和登录状态。这样就不需要在二次输入用户名和密码
    
    def timmer(func):
        def wapper(*args,**kwargs):
            start_time = time.time()
            f = func()
            end_time = time.time()
            print("run time is %s " % (end_time - start_time))
        return wapper
    
    def auth2(auth_type='file'):
        def auth(func):
            # print(auth_type)
            def wrapper(*args,**kwargs):
                if current_login['name'] and current_login['login']: #认证用户有值,直接执行认证后的执行函数。
                    res=func(*args,**kwargs)
                    return res
                if auth_type == 'file':
                    name=input('username: ')
                    password=input('password: ')
                    if name == 'wang' and password == '111':
                        print('auth successfull')
                        res=func(*args,**kwargs)
                        current_login['name']=name #记录登录状态。
                        current_login['login']=True
                        return res
                    else:
                        print('auth error')
                elif auth_type == 'sql':
                    print('还他妈不会玩')
            return wrapper
        return auth
    
    @timmer
    @auth2(auth_type='file') #@auth  #index=auth(index)
    def index():
        print('welcome to inex page')
    
    @auth2()
    def home():
        print('welcome to home page')
    
    
    #调用阶段
    index()
    home()

    ------------- END -----------

  • 相关阅读:
    Jocke的IOT之路--raspberrypi更换国内镜像
    利用PostMan 模拟上传/下载文件
    Java中的Lambda表达式
    设计模式之Jdk动态代理
    设计模式之代理模式
    Java内存模型及Java关键字 volatile的作用和使用说明
    JVM GC-----4、finalize()方法
    JVM GC-----3、垃圾对象的标记思路(二)
    JVM GC-----2、垃圾对象的标记思路(一)
    JVM GC-----1、垃圾回收算法
  • 原文地址:https://www.cnblogs.com/george92/p/13599096.html
Copyright © 2020-2023  润新知