当前位置: 首页 > news >正文

[python3] 装饰器

装饰器是Python中一种特殊的语法,用于在不修改原函数代码的情况下,为函数添加额外的功能。

  • 装饰器基于函数闭包和函数作为第一类对象的特性实现。
  1. 原理:

    • Python中的装饰器本质上是一个函数或类,它接受一个函数作为参数,并返回一个新的函数(或类)。
    • 装饰器通过在原函数周围包裹一层额外的逻辑来修改函数的行为,比如添加日志、缓存、权限验证等功能。
  2. 设计:

    • 装饰器通常使用函数定义来实现,也可以使用类来实现(类装饰器)。
    • 装饰器函数需要接受被装饰的函数作为参数,并返回一个新的函数。
    • 装饰器函数内部通常定义一个嵌套函数,用于对原函数进行包装,可以在嵌套函数中添加额外的逻辑。
    • 装饰器可以有多个,多个装饰器会按照从上到下的顺序依次进行装饰。
  3. 使用:

    • 使用装饰器时,可以使用@装饰器函数的语法将装饰器应用于目标函数。
    • 装饰器可以直接放置在目标函数定义的上方,会自动将目标函数作为参数传递给装饰器函数,并将返回的新函数赋值给目标函数名。
    • 也可以通过目标函数 = 装饰器函数(目标函数)的方式手动应用装饰器。
  4. 注意事项:

    • 装饰器会修改原函数的行为,因此在使用装饰器时要注意不要破坏原函数的预期功能。
    • 装饰器只在函数定义阶段执行一次,之后每次调用被装饰的函数,实际上是调用装饰器返回的新函数。
    • 装饰器可以接受参数,可以使用带有参数的装饰器来实现更灵活的功能增强。
    • 装饰器在一些框架和库中广泛应用,如Flask中的路由装饰器、Django中的身份验证装饰器等。

下面是几种生成装饰器的代码示例:

  1. 简单的函数装饰器:
def simple_decorator(func):def wrapper(*args, **kwargs):print("Before calling the function")result = func(*args, **kwargs)print("After calling the function")return resultreturn wrapper@simple_decorator
def greet(name):print(f"Hello, {name}")greet("Alice")
  1. 接受参数的函数装饰器:
def parametrized_decorator(prefix):def decorator(func):def wrapper(*args, **kwargs):print(f"{prefix}: Before calling the function")result = func(*args, **kwargs)print(f"{prefix}: After calling the function")return resultreturn wrapperreturn decorator@parametrized_decorator("LOG")
def add(a, b):return a + bresult = add(3, 4)
print(result)
  1. 类装饰器:
class ClassDecorator:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):print("Before calling the function")result = self.func(*args, **kwargs)print("After calling the function")return result@ClassDecorator
def multiply(x, y):return x * yresult = multiply(3, 5)
print(result)

多个装饰器

当一个函数被多个装饰器装饰时,装饰器的调用顺序是从下往上的,也就是从最靠近目标函数的装饰器开始执行,然后依次向外层装饰器执行,直到最外层的装饰器为止。这样的执行顺序确保了每个装饰器都能按照正确的顺序影响函数的行为。

下面是一个示例,演示了一个函数被多个装饰器装饰时的执行顺序:

def decorator1(func):def wrapper(*args, **kwargs):print("Decorator 1 - Before calling the function")result = func(*args, **kwargs)print("Decorator 1 - After calling the function")return resultreturn wrapperdef decorator2(func):def wrapper(*args, **kwargs):print("Decorator 2 - Before calling the function")result = func(*args, **kwargs)print("Decorator 2 - After calling the function")return resultreturn wrapper@decorator1
@decorator2
def example_func(message):print(f"Function executed with message: {message}")example_func("Hello, World!")

在上面的示例中,example_func函数被decorator1decorator2两个装饰器装饰。根据装饰器执行顺序的原则,首先会执行decorator2,然后再执行decorator1,最后才执行原始的example_func函数。因此,输出的结果会按照装饰器的嵌套顺序依次打印出相应的信息。

请记住,装饰器的执行顺序对于最终函数的行为可能会产生重要影响,因此在设计和使用装饰器时,务必注意装饰器的顺序以及各个装饰器之间的交互。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【计算机网络_应用层】https协议——加密和窃密的攻防
  • 阿里云-零基础入门推荐系统 【Baseline】
  • 数据库-DDL
  • 热点篇(三)-促进传统地产的数字化、网络化和智能化转型
  • 24.第12届蓝桥杯省赛真题题解
  • 揭晓照明灯十大公认品牌排行榜最新品牌,都有哪些品牌上榜呢?
  • 测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus
  • 20240311按键输入实验
  • 【Python】【Matplotlib】解决使用 plt.savefig() 保存的图片出现一片空白的问题
  • Leetcode : 1137. 高度检查器
  • M2-DIA
  • PieCloudDB Database 3月产品动态丨功能再度升级,安全机制更加完善
  • 2024 年 AI 垂直应用迅速落地,人人都可以获得AI红利
  • Mybatis从入门到CRUD到分页到日志到Lombok到动态SQL再到缓存
  • 矩阵相乘函数
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 2017-09-12 前端日报
  • ES2017异步函数现已正式可用
  • HashMap剖析之内部结构
  • HomeBrew常规使用教程
  • input的行数自动增减
  • iOS编译提示和导航提示
  • JS函数式编程 数组部分风格 ES6版
  • mysql 5.6 原生Online DDL解析
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • sublime配置文件
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 程序员最讨厌的9句话,你可有补充?
  • 十年未变!安全,谁之责?(下)
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 我的面试准备过程--容器(更新中)
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • (13)DroneCAN 适配器节点(一)
  • (2)STL算法之元素计数
  • (3)(3.5) 遥测无线电区域条例
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (转)jdk与jre的区别
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • ../depcomp: line 571: exec: g++: not found
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .Net 4.0并行库实用性演练
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .net下的富文本编辑器FCKeditor的配置方法
  • .NET与 java通用的3DES加密解密方法
  • @hook扩展分析
  • [BUUCTF 2018]Online Tool
  • [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
  • [C#学习笔记]LINQ