装饰器的编写及使用

装饰器的编写及使用

返回首页

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

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

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 -----------

原文地址:https://www.cnblogs.com/george92/p/13599096.html