探索Python的魔法:装饰器模式的奥秘

news2024/10/5 12:22:19

引言

装饰器模式是一种结构型设计模式,它通过创建一个包装对象来包含真实的对象,从而在不修改原有对象的基础上扩展其功能。在Python中,装饰器模式尤为流行,因为它提供了一种非常Pythonic的方式来增强函数或类的功能。

基础语法介绍

在Python中,装饰器是一种使用@语法的函数,它可以让其他函数在不改变其代码的前提下增加额外功能。装饰器的语法规则如下:

  1. 装饰器本身是一个函数,它接受一个函数作为参数并返回一个新的函数。
  2. 使用@decorator语法将装饰器应用于另一个函数。

基础实例

问题描述:假设我们需要记录函数执行的时间,我们可以使用装饰器来实现。

代码示例

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} executed in {end_time - start_time} seconds")
        return result
    return wrapper

@timer
def example_function(x):
    time.sleep(x)
    return x

result = example_function(2)

进阶实例

问题描述:在Web开发中,我们经常需要对请求进行权限检查。使用装饰器可以方便地实现这一功能。

高级代码实例

from functools import wraps

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not is_user_logged_in():
            raise Exception("You need to log in first.")
        return f(*args, **kwargs)
    return decorated_function

def is_user_logged_in():
    return True  # 假设用户已登录

@login_required
def protected_function():
    return "This is a protected resource."

实战案例

问题描述:在构建一个RESTful API时,我们希望记录每个请求的响应时间,并在发生错误时发送错误日志。

解决方案:使用装饰器来实现请求日志和错误处理。

代码实现

import logging
from flask import Flask, request, jsonify

app = Flask(__name__)

def log_request(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        start_time = time.time()
        try:
            response = f(*args, **kwargs)
            status_code = response.status_code
        except Exception as e:
            status_code = 500
            logging.error(f"Error in {f.__name__}: {str(e)}")
        finally:
            end_time = time.time()
            logging.info(f"{f.__name__} executed in {end_time - start_time} seconds with status code {status_code}")
        return response
    return decorated_function

@app.route('/data')
@log_request
def get_data():
    return jsonify({"data": "Some data"})

if __name__ == '__main__':
    app.run(debug=True)

扩展讨论

装饰器模式在Python中的应用非常广泛,它不仅可以用于日志记录和权限检查,还可以用于缓存、事务处理、性能监测等多个方面。装饰器模式的优点在于它提供了一种非侵入式的方式来增强功能,使得代码更加清晰和易于维护。

结语

通过本文的探讨,我们深入了解了装饰器模式在Python中的应用。从基础语法到实战案例,装饰器模式展示了其强大的功能和灵活性。希望这篇文章能够帮助你更好地理解和使用装饰器模式,让你的代码更加优雅和高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

目标检测 DAB-DETR(2022)

文章目录 前言Query是什么,Detr收敛速度慢的原因是什么?改进策略位置先验和模型框架设置温度系数 前言 本文认为原始的Detr系列论文中:可学习的object queries仅仅是给model预测box提供了锚点(中心点)信息&#xff0c…

SpringBoot环境下古典舞交流平台的快速开发

第三章 系统分析 3.1 可行性分析 需要使用大部分精力开发的古典舞在线交流平台为了充分降低开发风险,特意在开发之前进行可行性分析这个验证系统开发是否可行的步骤。本文就会从技术角度,经济角度,还有操作角度等进行综合阐述。 3.1.1技术可行…

Python案例--三数排序

一、引言 在信息爆炸的时代,我们每天都会接触到大量的数据。无论是工作中的报表、学习中的数据集,还是日常生活中的购物清单,数据的有序性对于提高效率和决策质量都至关重要。排序算法作为数据处理的基础工具,其重要性不言而喻。…

日记学习小迪安全27

感觉复制粘贴没有意思,而且还有点浪费时间,主要是学习,不是复制,那就复制别人的吧 第27关就参考这篇文章吧,以下大部分内容都是参考以下文章(侵权删除) 第27天:WEB攻防-通用漏洞&a…

芯片录-低压差线性稳压器AZ1084D-ADJE1失效记录与原理分析

背景 最近主板坏了,现象是主机不停重启,USB设备LED灯一会儿亮,一会儿灭。经过一些分析和定位,通过测温发现主板上AZ1084D-ADJE1芯片高达91摄氏度,进一步测量该芯片的输出引脚和接地引脚短路,初步推测某些原…

Shell-使用函数

在 Shell 脚本中,函数是由一段代码定义的,可以被重复调用。Shell 函数的定义和调用相对简单,并且它支持参数传递和返回值。错误处理在 Shell 中也非常重要,通常通过检查返回的状态码来判断是否有错误发生。 1.Shell 函数的定义和…

构建高效招聘流程:Spring Boot大学生就业系统

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…

28 基于51单片机的两路电压检测(ADC0808)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,通过ADC0808获取两路电压,通过LCD1602显示 二、硬件资源 基于KEIL5编写C代码,PROTEUS8.15进行仿真,全部资源在页尾,提供…

【中间件学习】Git的命令和企业级开发

一、Git命令 1.1 创建Git本地仓库 仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制,就必须创建出一个仓库出来。创建一个Git本地仓库对应的命令是 git init ,注意命令要在文件目录下执行。 hrxlavm-1lzqn7w2w6:~/gitcode$ pwd /home/hr…

Yocto - 使用Yocto开发嵌入式Linux系统_06 掌握Bitbake工具

Grasping the BitBake Tool 在上一章中,我们了解了元数据、元数据集合概念以及 conf/layer.conf 的重要性。在本章中,我们将更深入地研究元数据,了解配方如何相互依赖,并了解 BitBake 如何处理依赖关系。 In the previous chapter…

Python机器视觉:01- 利用列表和切片操作 - 做一个弧线和图片相交的mask区域

前言: Python的列表处理,在机器视觉中经常被用到,这里结合基本的概念机器视觉实践案例,成文如下: 本身将实现一个,弧线的mask填充:这个mask是我的一个天文项目的应用,目的在于将月…

冥想第一千三百零一天(1301)

1.今天上午溪溪和小侄子写作业,我带着桐桐去了惠济区的裕华广场永辉,给家人买了好吃的,下午4点半左右去了妈妈朋友家里摘石榴。 2.感谢父母,感谢朋友,感谢家人,感谢不断进步的自己。

JavaWeb 14.详解TCP协议的三次握手和四次挥手

目录 一、TCP协议与UDP协议 二、TCP协议 1、建立连接(三次握手) 过程 2、断开连接(四次挥手) 过程 国庆节快乐! 一文详解TCP协议中的三次握手建立连接和四次挥手断开连接 —— 24.10.3 一、TCP协议与UDP协议 tcp协议与…

【可答疑】基于51单片机的智能台灯(含仿真、代码、报告、演示视频等)

✨哈喽大家好,这里是每天一杯冰美式oh,985电子本硕,大厂嵌入式在职0.3年,业余时间做做单片机小项目,有需要也可以提供就业指导(免费)~ 🐱‍🐉这是51单片机毕业设计100篇…

MATLAB中minres函数用法

目录 语法 说明 示例 线性系统的迭代解 使用指定了预条件子的 minres 提供初始估计值 使用函数句柄代替数值矩阵 minres函数的功能是求解线性系统 - 最小残差法。 语法 x minres(A,b) x minres(A,b,tol) x minres(A,b,tol,maxit) x minres(A,b,tol,maxit,M) x mi…

CPU性能篇-平均负载-Day 01

1. 平均负载 1.1 什么是平均负载 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。 1.1.1 什么是可运行状态 指正在使用 CPU 或者正在等待 CPU 的进程&#xff…

如何轻松查看你的 Windows 版本? 检查电脑Windows版本号五种方法

很多朋友发现windows拥有许多版本,比如如家庭版、企业版、专业版和教育版等,而每个版本都有相应的版本号,那么,怎么知道电脑windows版本呢?下面分享五种查看方法 自 1985 年首次推出以来,Windows 操作系统…

IntelliJ IDEA 2024.2 新特性概览

文章目录 1、重点特性:1.1 改进的 Spring Data JPA 支持1.2 改进的 cron 表达式支持1.3 使用 GraalJS 作为 HTTP 客户端的执行引擎1.4 更快的编码时间1.5 K2 模式下的 Kotlin 性能和稳定性改进 2、用户体验2.1 改进的全行代码补全2.2 新 UI 成为所有用户的默认界面2.3 Search E…

利用CRITIC客观权重赋权法进行数值评分计算——算法过程

1、概述 ‌CRITIC客观评价法是一种基于指标的对比强度和指标之间的冲突性来确定指标客观权数的方法。‌ 该方法适用于判断数据稳定性,并且适合分析指标或因素之间有着一定的关联的数据‌。 CRITIC方法的基本原理包括两个主要概念:对比强度和指标之间的…

Linux学习笔记(六):服务管理,监控,RPM包管理,yum包管理工具,Linux启动管理,网络管理

Linux学习笔记(六):服务管理,监控,RPM包管理,yum包管理工具,Linux启动管理,网络管理 1. 服务管理 1.1 service 启动/停止服务 service 命令是最常用的服务管理工具之一&#xff0c…