Python装饰器(decorators)


本文改编自以下文章:Decorators in Python


装饰器是一个很强大的工具,它允许我们很便捷地修改已有函数或者类的功能,我们可以用装饰器把另一个函数包装起来,扩展一些功能而不需要去修改这个函数代码。

预备知识

在Python中,函数是第一类对象,也就是说,Python中的函数可以作为参数来使用或传递,它具有如下属性:

  • 可以将函数存储在变量中
  • 可以将函数作为参数传递给另一个函数
  • 可以在函数中 return 另一个函数
  • 可以将函数存储在数据结构中,如哈希表,列表等

【例 1】将函数视为对象

在上面例子中,我们把函数up赋值给变量up1。这个操作并不会调用函数,而只是给函数up取了个别名up1

【例 2】将函数作为参数传递

上面例子中,函数dream的参数uplow也是函数

【例 3】从函数中 return 函数

这边比较绕,注意create_adder(15)返回的是一个函数,这个函数等同于adder,并且其内参数x是15。

最简单的装饰器

这边给出一个装饰器:

可以看到,装饰器就是把一个函数作为参数传进去,它本身也是个函数,把传进去的函数包装完之后,再把函数传出来。

我们把装饰器当成函数,正常调用就是上面这样。当然,装饰器有它特殊的用法,比如像这样:

它的工作逻辑就是把我定义的函数paper1当成参数传递给我的装饰器decorator,再传出来,当然我也可以把装饰器当成函数直接调用,就是麻烦一点罢了。

装饰器的语法逻辑是这样的:

python 复制代码
@decorator
def func():
    print("果壳小旋子")

'''Above code is equivalent to -

def func():
    print("果壳小旋子")
    
func = decorator(func)'''

【例 4】计算代码运行时间的装饰器

python 复制代码
# importing libraries
import time
import math
 
# decorator to calculate duration
# taken by any function.
def calculate_time(func):
     
    # added arguments inside the inner1,
    # if function takes any arguments,
    # can be added like this.
    def inner1(*args, **kwargs):
 
        # storing time before function execution
        begin = time.time()
         
        func(*args, **kwargs)
 
        # storing time after function execution
        end = time.time()
        print("Total time taken in : ", func.__name__, end - begin)
 
    return inner1

装饰器的作用很明显了,当我需要计算某一个函数的运行时间时,我只要找到那个函数的定义,在前面@calculate_time就行了,不需要再一个一个修改函数,当我不需要计算时间的时候,把装饰器删掉就行了。

被装饰的函数需要传参,有返回值

python 复制代码
def hello_decorator(func):
    def inner1(*args, **kwargs):
         
        print("before Execution")
         
        # getting the returned value
        returned_value = func(*args, **kwargs)
        print("after Execution")
         
        # returning the value to the original frame
        return returned_value
         
    return inner1

上面的装饰器中的内层函数inner1可以接收参数*args, **kwargs,并且可以返回值returned_value*args表示可以接受任意长度的位置参数,**kwargs表示可以接受任意长度的关键字参数。

多个装饰器连用

如果我有多个装饰器来装饰同一个函数,会是什么情况?首先定义两个装饰器:

python 复制代码
# code for testing decorator chaining
def decor1(func):
    def inner():
        x = func()
        return x * x
    return inner
 
def decor(func):
    def inner():
        x = func()
        return 2 * x
    return inner

装饰器decor将函数返回值加倍,装饰器decor1将函数返回值乘方

等价于

python 复制代码
decor1(decor(num))
decor(decor1(num2))

想了解带有参数的Python装饰器,可以参考Python 带参数的装饰器

相关推荐
Ada's1 天前
【计算机基础系列】python语言:环境搭建
开发语言·python
m沐沐1 天前
【机器学习】信用卡欺诈检测实战:逻辑回归 + 下采样
人工智能·python·机器学习·pycharm·逻辑回归·numpy
好好学仿真1 天前
机器学习预测聚合物拉伸强度:五种回归算法对比(附Kaggle数据集 + 五折交叉验证)
python·机器学习·xgboost·梯度提升·材料性能预测·随机森林回归
宸津-代码粉碎机1 天前
Spring AI 企业级RAG实战|增量更新+文档去重+定时自动入库生产落地方案
java·大数据·人工智能·后端·python·spring
正在走向自律1 天前
告别低效繁琐!DeepSeek+Python 重塑科研绘图新范式
python·开发工具·deepseek·ai辅助编程
曾阿伦1 天前
Unicode 正则表达式开发指南
python·正则表达式
香辣西红柿炒蛋1 天前
yaml文件介绍、数据读取
python
乐于分享的阿乐1 天前
(二)VSCode搭建python环境(详细图文保姆级教程)
ide·vscode·python
weixin_408099671 天前
2026 AI生成图片快速去水印的5种实测方法(附在线工具 + Python/Java/PHP API代码)
java·人工智能·python·api接口·ai去水印·石榴智能·自动去水印
2601_961194021 天前
2026初级会计经济法基础知识点汇总
python·django·pdf·virtualenv·代理模式·pygame