首页 > 编程语言 >Python - 【装饰器】详解

Python - 【装饰器】详解

时间:2023-12-09 17:32:01浏览次数:62  
标签:return 函数 Python args 详解 def func 装饰 decorator


一. 概念

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 - 【装饰器】的基本使用介绍,希望对你有所帮助!


标签:return,函数,Python,args,详解,def,func,装饰,decorator
From: https://blog.51cto.com/u_15349841/8750996

相关文章

  • Python - 实现【单例模式】的四种方法
    方法一:使用模块实现单例模式在Python中,每个模块只会被导入一次,因此可以将需要实现单例模式的类定义在一个模块中,每次需要使用该类时,将该模块导入即可。#singleton.pyclassSingleton:passsingleton=Singleton()在其他模块中直接引用这个singleton对象即可。2.方法二:使......
  • 【JavaSE】数据结构-哈希表(HashSet/HashMap底层哈希表详解,源码分析)
    哈希表结构JDK8版本之前:数组+链表JDK8版本及之后:数组+链表+红黑树哈希表HashMapput()方法的添加流程创建HashSet集合时,构造方法中自动创建HashMap集合;HashMap空参构造方法会创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table(tips:实际上,HashSet对象创建后,第......
  • [Python]运算符: / 和 % 和 //计算差异是什么?
    /和%和//(地板除)在Python中的作用是:用于对数据进行除法运算。python中与除法相关的三个运算符是//和/和%,下面逐一讲解。“/”,这是传统的除法,5/2=2.5“//”,在python中,这个叫“地板除”,3//2=1“%”,这个是取模操作,也就是区余数,8%2=0,7%2=1Python中分为3种除法:1、/,2、%,3......
  • Java开发者的Python快速进修指南:实战之跳表pro版本
    之前我们讲解了简易版的跳表,我希望你能亲自动手实现一个更完善的跳表,同时也可以尝试实现其他数据结构,例如动态数组或哈希表等。通过实践,我们能够发现自己在哪些方面还有所欠缺。这些方法只有在熟练掌握之后才会真正理解,就像我在编写代码的过程中,难免会忘记一些方法或如何声明属性等......
  • Python 潮流周刊第 30 期(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。周刊全文:https://pythoncat.top/posts/2023-12-09-weekly以下是本期摘要:......
  • 深入探究 Python 异步编程:利用 asyncio 和 aiohttp 构建高效并发应用
    在现代编程中,异步编程已成为处理高并发和IO密集型任务的重要方式。Python提供了强大的异步编程支持,包括asyncio库和aiohttp等框架。本文将深入探讨异步编程的概念,以及在Python中如何利用异步框架来实现高效的并发编程。1.异步编程概念异步编程允许程序在等待IO操作完成时......
  • 详解十大经典排序算法(六):快速排序(QuickSort)
    算法原理分区(Partition):选择一个基准元素,将数组分为两个子数组,小于基准的放在左边,大于基2准的放在右边。递归排序:对左右两个子数组分别进行快速排序。合并:不需要实际的合并操作,因为在分解和递归排序阶段已经完成了排序。算法描述快速排序是一种基于分治思想的高效排序算法,由英国......
  • python+sklearn 机器学习代码备忘
    importsklearnfromsklearn.model_selectionimporttrain_test_splitfromsklearn.linear_modelimportLinearRegressionimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsfromsklearnimportpreprocessingimportcsvimportnumpyas......
  • Python 变量类型
    变量是存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。变量赋值Python中的变量赋值不需要类型声明。每个变量在内存......
  • Python算法——快速排序
    快速排序(QuickSort)是一种高效的分治排序算法,它选择一个基准元素,将数组分成两个子数组,小于基准的放在左边,大于基准的放在右边,然后递归地排序子数组。快速排序通常比冒泡排序和选择排序更高效,特别适用于大型数据集。本文将详细介绍快速排序的工作原理和Python实现。快速排序的工作原......