python装饰器的介绍及应用

106 阅读2分钟

一 简介

Python装饰器(decorator)是一种设计模式,它允许你在不改变函数内部代码的情况下,动态地给函数添加功能。装饰器本质上是一个返回函数的高阶函数(higher-order function)。装饰器的主要作用是修改或扩展函数的行为。

二 基础语法

函数在python中也属于一等对象,意味着函数可以作为一个参数传递给另一个函数


def square(x):
    return x*x
​
​
def print_running(f,x):
    print(f'{f.__name__} is running')
    return f(x)
​
​
result = print_running(square,2) #square is running
print(result) # 4

装饰器本质也是一个函数,将装饰的函数当作一个参数传递给装饰器并返回一个新的函数,新函数在包含传入函数的同时扩充了其他的功能,调用装饰过的函数即为调用这个返回的新函数


#测量函数运行时间
import time
def decoretor(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        print(f'{func.__name__} is running')
        result = func(*args,**kwargs)
        end_time = time.time()
        print(end_time-start_time)
        return result
    return wrapper
​
@decoretor
def square(x):
    return x*x   #square is running 3.7670135498046875e-05

装饰器生成器

根据传入的参数生成不同的装饰器,传入不同的阈值可以测量自行调整阈值,以测量函数运行时间是否超过阈值


import functools
def timer(threshold):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args,**kargs):
            start_time = time.time()
            result = func(*args,**kargs)
            end_time = time.time()
            if end_time - start_time >= threshold:
                print(f'{func.__name__} took longer')
            return result
        return wrapper
    return decorator
​
@timer(0.2)
def sleep_04():
    time.sleep(0.4)
​
​
sleep_04()   # sleep_04 took longer

三 常见场景

  1. 日志记录:在函数调用前后记录日志。
  2. 访问控制:检查用户是否有权限执行某个操作。
  3. 性能计时:计算函数的执行时间。
  4. 缓存:将函数的返回值缓存起来,以提高性能。

四 类装饰器

除了函数装饰器,Python 还支持类装饰器。类装饰器通过定义__call__方法,可以像函数一样调用。

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hello():
    print("Hello!")

say_hello() # Call 1 of say_hello Hello!
say_hello() # Call 2 of say_hello Hello!