欢迎访问宙启技术站
智能推送

Python中函数的装饰器(Decorator)的使用方法和应用场景

发布时间:2023-09-17 20:04:44

装饰器是Python中一种强大的特性,它能够在不修改被装饰函数源码的情况下,动态地添加功能。本文将介绍Python中函数的装饰器的使用方法和应用场景。

一、装饰器的使用方法

1. 定义装饰器

装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。通常情况下,装饰器会使用闭包来实现。

以下是一个示例装饰器的定义:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 添加装饰功能
        return func(*args, **kwargs)
    return wrapper

2. 使用装饰器

使用装饰器时,需要在被装饰函数的定义之前加上装饰器的语法糖@,后面紧跟着装饰器函数的名称。

以下是一个示例被装饰函数的定义和装饰器的使用:

@decorator
def func():
    pass

二、装饰器的应用场景

1. 计时器

装饰器可以用于计算函数的执行时间,可以在函数执行之前和之后记录时间,然后计算时间差。这在调优代码性能时非常有用。

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print('函数 {} 的执行时间为:{} 秒'.format(func.__name__, end_time - start_time))
        return result
    return wrapper

@timer
def long_running_function():
    time.sleep(2)

long_running_function()

2. 权限验证

装饰器可以用于对需要进行权限验证的函数进行包装,以确保只有具有相应权限的用户才能执行该函数。

def login_required(func):
    def wrapper(*args, **kwargs):
        if user.is_authenticated:
            return func(*args, **kwargs)
        else:
            raise Exception('请先登录')
    return wrapper

@login_required
def access_sensitive_info():
    pass

3. 日志记录

装饰器可以用于记录函数的调用日志,包括函数名称、参数和返回结果。这在程序调试和错误追踪时非常有用。

def logger(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print('函数 {} 被调用,参数为:{},结果为:{}'.format(func.__name__, args, result))
        return result
    return wrapper

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

add(1, 2)

4. 缓存

装饰器可以用于缓存函数的返回结果,以避免重复执行耗时的计算过程,提高代码的执行效率。

def cache(func):
    cache = {}

    def wrapper(*args, **kwargs):
        key = str(args) + str(kwargs)
        if key in cache:
            return cache[key]
        else:
            result = func(*args, **kwargs)
            cache[key] = result
            return result
    return wrapper

@cache
def fib(n):
    if n <= 1:
        return n
    else:
        return fib(n-1) + fib(n-2)

fib(10)

5. 日志处理

装饰器可以用于处理函数的异常,捕获异常并记录到日志中,使得代码更加健壮和容错。

import logging

def exception_handler(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            logging.error('函数 {} 抛出异常:{}'.format(func.__name__, str(e)))
    return wrapper

@exception_handler
def divide(a, b):
    return a / b

divide(10, 0)

在实际应用中,还有很多其他的场景可以使用装饰器,比如输入参数验证、函数重试、缓存失效策略等等。通过使用装饰器,可以更加灵活和高效地改进现有的函数功能,代码可读性也会大大提高。