装饰器

普通装饰器:用于查看函数运行时间

def use_time(fun):
    def inner(*args,**kwargs):
        start_time = time.time()
        result = fun()
        stop_time = time.time()
        print("任务执行使用时间%s秒" % (stop_time-start_time))
        return result
    return inner

@use_time
def fun():
    for i in range(1000000):
        pass
    return "success"
查看时间装饰器

复杂装饰器:装饰器带参数

import time
user,passwd = 'aaa','123'
def auth(auth_type):
    print("auth func:",auth_type)
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            print("wrapper func args:", *args, **kwargs)
            if auth_type == "local":
                username = input("Username:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print("33[32;1mUser has passed authentication33[0m")
                    res = func(*args, **kwargs)  # from home
                    print("---after authenticaion ")
                    return res
                else:
                    exit("33[31;1mInvalid username or password33[0m")
            elif auth_type == "ldap":
                print("搞毛线ldap,不会。。。。")

        return wrapper
    return outer_wrapper

def index():
    print("welcome to index page")
@auth(auth_type="local") # home = wrapper()
def home():
    print("welcome to home  page")
    return "from home"

@auth(auth_type="ldap")
def bbs():
    print("welcome to bbs  page")

index()
print(home()) #wrapper()
bbs()
带参数的装饰器

从表面上来看,函数的代码和盗用方法都没有改变。但是实际上,你在调用被装饰函数fun()时,在装饰器中已经改变了函数的名字,此时调用的是装饰器中的内层函数inner()。

因此,为了不改变被装饰函数的名称,我们用@functools.wraps()来防止函数的名称被改变。

from functools import wraps

def log(func):
    @wraps(func)  # 防止函数的名字被改变
    def inner(*args, **kwargs):
        print('call %s()' % tete.__name__)
        return func(*args, **kwargs)

    return inner


@log
def tete(x,y):
       print(x+y)
原文地址:https://www.cnblogs.com/ppzhang/p/10403405.html