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

深入探讨 Python 中的装饰器和上下文管理器

Python 作为一门灵活而强大的语言,提供了许多高级特性,其中装饰器(Decorators)和上下文管理器(Context Managers)是其中两个非常有用的概念。这两个功能性特性提供了对代码结构和行为进行修改和控制的强大工具。它们允许程序员在不修改源代码的情况下,添加、修改或扩展函数或类的功能,帮助编写更优雅、更干净的代码,同时提高代码的可重用性和可维护性。

1.装饰器(Decorators)

装饰器是函数的函数,它接受一个函数作为参数,并返回一个新的函数。它们提供了一种简洁的方式来包装或修改函数的行为。通过装饰器,可以在不改变原始函数代码的情况下,添加额外的功能或逻辑,如日志记录、性能计时、权限检查等。这种能力使得装饰器成为Python中函数式编程范式的强大工具之一。

1.1. 基本语法

def decorator_function(func):def wrapper(*args, **kwargs):# 添加装饰逻辑return func(*args, **kwargs)return wrapper@decorator_function
def some_function():# 函数体pass
1. 示例一: 计时器装饰器
import timedef timer(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()print(f"Execution time: {end_time - start_time} seconds")return resultreturn wrapper@timer
def some_function():time.sleep(2)print("Function executed")some_function()
# 输出:Function executed
#      Execution time: 2.000123 seconds
2. 示例二:权限检查装饰器
def check_permission(func):def wrapper(*args, **kwargs):if user_has_permission():return func(*args, **kwargs)else:raise PermissionError("Permission denied")return wrapper@check_permission
def sensitive_operation():print("Operation executed")sensitive_operation()
# 如果用户有权限,输出:Operation executed
# 如果用户无权限,抛出 PermissionError

2. 上下文管理器(Context Managers)

上下文管理器提供了对资源进行安全获取和释放的机制,即使在出现异常时也能确保资源的释放。这对于处理文件、数据库连接或其他需要资源管理的情况特别有用。上下文管理器可以使用 with 语句来确保在代码块执行前获取资源,在代码块执行后释放资源,保证资源的正确处理。

2.1. 基本语法

class CustomContextManager:def __enter__(self):# 分配资源return resourcedef __exit__(self, exc_type, exc_value, traceback):# 释放资源passwith CustomContextManager() as resource:# 使用资源的代码块pass
3. 示例三:文件操作的上下文管理器
class FileManager:def __init__(self, filename, mode):self.filename = filenameself.mode = modedef __enter__(self):self.file = open(self.filename, self.mode)return self.filedef __exit__(self, exc_type, exc_value, traceback):self.file.close()with FileManager("example.txt", "w") as file:file.write("Hello, Context Manager!")
# 文件 example.txt 被正确地写入数据,并在代码块结束时自动关闭
4. 示例四:数据库连接的上下文管理器
import sqlite3class DatabaseConnection:def __init__(self, database):self.database = databasedef __enter__(self):self.connection = sqlite3.connect(self.database)return self.connectiondef __exit__(self, exc_type, exc_value, traceback):self.connection.close()with DatabaseConnection("example.db") as conn:cursor = conn.cursor()cursor.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
# 在代码块中成功创建数据库连接,并在结束时自动关闭连接

3. 高阶概念与应用

  • 装饰器链:多个装饰器可以被串联使用,以添加多个功能。
  • 上下文管理器的异步支持async with 语句在异步代码中管理异步资源的获取和释放。

这些高级特性提供了对 Python 代码逻辑和资源管理更细粒度的控制,使得代码更具灵活性和可维护性。

4. 结语

装饰器和上下文管理器是 Python 中强大而灵活的特性,它们可以使代码更简洁、更易于维护,并且提供了许多便利。

相关文章:

深入探讨 Python 中的装饰器和上下文管理器

Python 作为一门灵活而强大的语言,提供了许多高级特性,其中装饰器(Decorators)和上下文管理器(Context Managers)是其中两个非常有用的概念。这两个功能性特性提供了对代码结构和行为进行修改和控制的强大工…...

比whatsapp效果好---Google Messages RCS协议消息推送

这段时间由于使用谷歌手机Pixel 7 ( Android13)研究改机room,看了很多相关的资料,测试研究了谷歌生态很多软件功能。结果就是改机Room还没编译成功,反而是测试出Google Messages群发功能的bug,算是一个惊喜…...

HBuilder X

选择一款编程软件有以下几个好处: (1)提高效率:编程软件通常强调代码编辑和自动完成,可以帮助程序员更快速、更准确地输入代码。 (2)降低错误率:编程软件还可以检测代码中的错误&a…...

异地现场工控设备,如何实现远程配置、调试?

南京某企业专注于工业物联领域,在相关项目中往往会在各个点位部署基于Linux系统的中控主机,实现各类物联设备信息的采集、汇总。但是,由于各点位分散多地,且数量达到了上百个,虽然中控主机具备4G物联网接入能力&#x…...

C++报错:error C2238: 意外的标记位于“;”之前

报错信息如下: 编译遇见这样的错误信息主要有一下几种: 情况一: 多数情况下出现这种问题的原因是因为头文件重复包含:即头文件A包含了B,头文件B又包含了A,导致编译器在加载头文件时陷入死循环。 解决办法…...

五、Microsoft群集服务(MSCS)环境的搭建

一、【目的】 学会利用Windows Server布置群集环境。 二、【设备】 FreeNAS11.2,Windows Server 2019 三、【要求】 学会利用Windows Server布置群集环境,掌握处理问题的能力。 配置表: 节点公网IP(public)内网IP(private)群集IP(clust…...

通义千问 Qwen-72B-Chat在PAI-DSW的微调推理实践

01 引言 通义千问-72B(Qwen-72B)是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛,包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上,使用对齐机制打造的…...

web应用体系以及windows网络常见操作应用

本课程目标 1.Dos命令(必须掌握) 2.网络体系(笔试选择填空题) 3.搭建windows测试环境 一、Dos命令 1.DOS窗口启动 启动方式1.进入DOS页面:win+R,键入cmd 启动方式2.开始-运行--输入cmd-回车,此时将出现一个显示命令提示符的窗口,如下图 2、常见的Dos命令: 1、cd…...

FFmpeg 安装配置

FFmpeg 安装配置 依赖包 sudo apt-get install -y autoconf automake bzip2 cmake freetype-devel gcc gcc-c git libtool make mercurial pkgconfig zlib-devel x264-develsudo apt-get install yasm -y安装 wget https://ffmpeg.org/releases/ffmpeg-4.2.3.tar.bz2tar -…...

14:00面试,14:08就出来了,问的问题有点变态。。。。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...

vue3 添加编辑页使用 cron 表达式生成

示例效果图 1、添加组件 <template><div class"v3c"><ul class"v3c-tab"><li class"v3c-tab-item" :class"{ v3c-active: tabActive 1 }" click"onHandleTab(1)">秒</li><li class&qu…...

洛谷P1722 矩阵Ⅱ——卡特兰数

传送门&#xff1a; P1722 矩阵 II - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1722 用不需要除任何数的公式来求。 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cmath> #includ…...

Unity | Shader基础知识(第六集:语法<如何加入外部颜色资源>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、语法结构 1 复习 2 理论知识 3 Shader里声明的写法 4 Properties和SubShader毕竟不是一家人 三、 片元着色器中使用资源 四、代码实现 五、全部代码 六、下集介绍 相关阅读 Unity - Manual: Writing Surface Shaders…...

使用opencv的Laplacian算子实现图像边缘检测

1 边缘检测介绍 图像边缘检测技术是图像处理和计算机视觉等领域最基本的问题&#xff0c;也是经典的技术难题之一。如何快速、精确地提取图像边缘信息&#xff0c;一直是国内外的研究热点&#xff0c;同时边缘的检测也是图像处理中的一个难题。早期的经典算法包括边缘算子方法…...

5. PyTorch——数据处理模块

1.数据加载 在PyTorch中&#xff0c;数据加载可通过自定义的数据集对象。数据集对象被抽象为Dataset类&#xff0c;实现自定义的数据集需要继承Dataset&#xff0c;并实现两个Python魔法方法&#xff1a; __getitem__&#xff1a;返回一条数据&#xff0c;或一个样本。obj[in…...

Android 移动端编译 cityhash动态库

最近做项目&#xff0c; 硬件端 需要 用 cityhash 编译一个 动态库 提供给移动端使用&#xff0c;l 记录一下 编译过程 city .cpp // // Created by Administrator on 2023/12/12. // // Copyright (c) 2011 Google, Inc. // // Permission is hereby granted, free of charg…...

IO流学习

IO流:存储和读取数据的解决方案 import java.io.FileOutputStream; import java.io.IOException;public class Test {public static void main(String[] args) throws IOException {//1.创建对象//写出 输入流 OutputStream//本地文件fileFileOutputStream fos new FileOutputS…...

新手HTML和CSS的常见知识点

​​​​ 目录 1.HTML标题标签&#xff08;到&#xff09;用于定义网页中的标题&#xff0c;并按照重要性递减排列。例如&#xff1a; 2.HTML段落标签&#xff08;&#xff09;用于定义网页中的段落。例如&#xff1a; 3.HTML链接标签&#xff08;&#xff09;用于创建链接…...

RocketMQ系统性学习-RocketMQ领域模型及Linux下单机安装

MQ 之间的对比 三种常用的 MQ 对比&#xff0c;ActiveMQ、Kafka、RocketMQ 性能方面&#xff1a; 三种 MQ 吞吐量级别为&#xff1a;万&#xff0c;百万&#xff0c;十万消息发送时延&#xff1a;毫秒&#xff0c;毫秒&#xff0c;微秒可用性&#xff1a;主从&#xff0c;分…...

微服务架构之争:Quarkus VS Spring Boot

在容器时代&#xff08;“Docker时代”&#xff09;&#xff0c;无论如何&#xff0c;Java仍然活着。Java在性能方面一直很有名&#xff0c;主要是因为代码和真实机器之间的抽象层&#xff0c;多平台的成本&#xff08;一次编写&#xff0c;随处运行——还记得吗&#xff1f;&a…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...