一. 概念

Python装饰器本质上是一个函数,用于修改其他函数的功能。
装饰器可以在不改变函数代码的情况下添加新的功能,使代码更具可读性、可维护性和可重用性。使用装饰器可以把一个函数传递给另一个函数,使其具有新的行为,而无需修改函数本身的代码。

二. 基本语法

@decorator_name
def function_name():
    do something

其中,decorator表示装饰器函数,function表示被装饰的函数。在执行function()时,实际上是先执行了decorator(function),然后把decorator(function)的返回值作为function的返回值。这样,就可以在不修改原来函数代码的情况下,通过装饰器来增强函数的功能。

三. 示例代码

1. 基本使用

下面是一个简单的装饰器的示例,用来打印函数的执行时间:

import time


def timing_decorator(function):
    print('start doing decorator func...')

    def wrapper(*args, **kwargs):
        start = time.time()
        result = function(*args, **kwargs)
        end = time.time()
        print("{} took {} seconds to execute".format(function.__name__, end - start))
        return result

    return wrapper


@timing_decorator
def my_func():
    print('start doing my_func......')
    time.sleep(1)
    print('end doing my_func......')
    return 'end...'


print(my_func())

这个装饰器会在被装饰的函数执行前打印当前时间,然后在函数执行后再次打印,从而计算函数执行的时间。在这个例子中,@timing_decorator语法表示把timing_decorator函数作为my_func函数的装饰器。

运行结果

start doing decorator func...
start doing my_func......
end doing my_func......
my_func took 1.0100395679473877 seconds to execute
end...

2. 带有参数的用法

def print_params_decorator(*param_names):
    def decorator(function):
        def wrapper(*args, **kwargs):
            params_to_print = [arg for i, arg in enumerate(args) if function.__code__.co_varnames[i] in param_names]
            print("Parameters: {}".format(params_to_print))
            return function(*args, **kwargs)
        return wrapper
    return decorator
  
@print_params_decorator('a', 'c')
def my_func(a, b, c):
    pass

my_func(1, 2, 3)

这个装饰器会在函数执行前打印参数a和c的值,然后再执行原函数。运行这个程序,可以得到如下输出:

运行结果

Parameters: [1, 3]

可以看到,装饰器打印了a和c的值,而没有打印b的值。这个例子中的装饰器带有参数,所以需要用两层嵌套来定义它,第一层嵌套接收参数,第二层嵌套接收函数并返回一个新的函数。

四. 常用应用场景

1. 日志记录

使用装饰器来实现日志记录是一种常见的应用场景。可以在函数调用前后记录日志,以帮助调试和维护。

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info("Calling function: {0}".format(func.__name__))
        result = func(*args, **kwargs)
        logging.info("Result: {0}".format(result))
        return result
    return wrapper

@log_decorator
def add(x, y):
    return x + y

2. 认证和授权

使用装饰器来实现认证和授权也是很常见的应用场景。可以在函数调用前检查用户是否已登录,并验证其权限。

def login_required(func):
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('/login/')
        else:
            return func(request, *args, **kwargs)
    return wrapper

@login_required
def home(request):
    return render(request, 'home.html')

3. 缓存

使用装饰器来实现缓存是一种优化技术,可以缓存一个函数的结果,以避免重复计算。

def cache_decorator(func):
    cache = {}
    def wrapper(*args):
        if args in cache:
            return cache[args]
        result = func(*args)
        cache[args] = result
        return result
    return wrapper

@cache_decorator
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

总结:

使用装饰器可以把一个函数传递给另一个函数,使其具有新的行为,而无需修改函数本身的代码。

以上就是Python - 【装饰器】的基本使用介绍,希望对你有所帮助!