无参装饰器

#1. decorator without arguments
def log_time_always(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        #1. get current time
        t1 = datetime.now()
        #2. run the function
        func(*args, **kwargs)
        #3. get current time
        t2 = datetime.now()
        print(f'in {func.__name__}, it took {t2-t1}')

    return wrapped

带参数的装饰器

#2. decorator with arguments, flag is True or False
def log_time(flag):
    def wrapper(func):
        @wraps(func)
        def wrapped(*args, **kwargs):
            # if flag is true, we need to log the time
            if flag:
                #1. get current time
                t1 = datetime.now()
                #2. run the function
                func(*args, **kwargs)
                #3. get current time
                t2 = datetime.now()
                print(f'in {func.__name__}, it took {t2-t1}')
            else:
                func(*args, **kwargs)
        return wrapped
    return wrapper

本质

  • 装饰器需要能够处理一个函数

无参

@decorator_1
def f():
  pass

等同于

def f():
  pass

f = decorator_1(f)

带参

@decorator_2('ok')
def f():
  pass

等同于

def f():
  pass

f = decorator_1('ok')(f)