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

1.3 装饰器与上下文管理器

第一阶段 · 1.3 装饰器与上下文管理器学习目标彻底掌握 Python 中用于代码复用和资源管理的高级特性理解它们在 FastAPI 中的底层应用。预计用时2 天每天约 3 小时重要程度⭐⭐⭐⭐FastAPI 的依赖注入、路由定义、生命周期管理大量依赖这两个特性 为什么先学这个在 FastAPI 的开发中你几乎每天都会和它们打交道装饰器app.get(/)就是一个装饰器它将你的普通函数变成了 HTTP 路由。上下文管理器当你连接数据库如async with session:或者管理 FastAPI 的启动和关闭Lifespan时都会用到它。一句话总结掌握了装饰器你就能看懂 FastAPI 是怎么把路由和函数绑定的掌握了上下文管理器你就学会了如何优雅且安全地管理数据库等外部资源。 第一部分装饰器 (Decorators)1. 什么是装饰器装饰器本质上是一个函数。它的作用是在不修改原函数代码的前提下给原函数增加额外的功能比如打印日志、计算耗时、权限校验。你可以把它想象成一个包装盒你把原来的函数放进盒子里盒子外面加了点新花样然后再把盒子还给你。# ❌ 没有装饰器你需要修改原函数代码来增加计时功能importtimedefheavy_computation():start_timetime.time()print(开始计算...)time.sleep(1)print(计算结束)end_timetime.time()print(f耗时:{end_time-start_time}秒)# ✅ 有装饰器原函数保持纯粹计时功能被抽离出来importtime# 这是一个装饰器deftimer_decorator(func):defwrapper(*args,**kwargs):start_timetime.time()resultfunc(*args,**kwargs)# 执行原来的函数end_timetime.time()print(f函数{func.__name__}执行耗时:{end_time-start_time:.4f}秒)returnresultreturnwrapper# 使用 语法糖应用装饰器timer_decoratordefheavy_computation():print(开始计算...)time.sleep(1)print(计算结束)heavy_computation()# 输出:# 开始计算...# 计算结束# 函数 heavy_computation 执行耗时: 1.00xx 秒2. functools.wraps保留原函数的身份证当你使用装饰器时实际上发生的是偷梁换柱。timer_decorator相当于执行了heavy_computation timer_decorator(heavy_computation)。此时heavy_computation已经变成了内部的wrapper函数这会导致原函数的名字__name__和注释__doc__丢失。在 FastAPI 中框架依赖这些元信息来生成 Swagger API 文档所以丢失元信息是致命的。fromfunctoolsimportwrapsdefmy_decorator(func):# 使用 wraps 将原函数 (func) 的名字和注释复制给 wrapperwraps(func)defwrapper(*args,**kwargs):print(调用前执行)returnfunc(*args,**kwargs)returnwrappermy_decoratordefsay_hello():这是一个打招呼的函数print(Hello!)# 因为用了 wraps下面两行输出正常print(say_hello.__name__)# 输出: say_helloprint(say_hello.__doc__)# 输出: 这是一个打招呼的函数⚠️强制规范以后只要写装饰器必须加上wraps(func)3. 带参数的装饰器有时候我们希望装饰器本身也能接收参数。比如写一个重试装饰器我们希望指定重试次数。这就需要在装饰器外面再包一层函数被称为装饰器工厂。fromfunctoolsimportwrapsimporttime# 第一层接收装饰器参数defretry(max_retries3,delay1): 当函数抛出异常时自动重试 # 第二层真正的装饰器接收原函数defdecorator(func):wraps(func)# 第三层包装器执行实际逻辑defwrapper(*args,**kwargs):forattemptinrange(1,max_retries1):try:returnfunc(*args,**kwargs)exceptExceptionase:print(f[{func.__name__}] 第{attempt}次失败:{e})ifattemptmax_retries:raisee# 最后一次失败则向上抛出time.sleep(delay)returnwrapperreturndecorator# 使用带参数的装饰器retry(max_retries2,delay0.5)defunstable_request():print(发起网络请求...)raiseConnectionError(网络超时)# 运行 unstable_request() 会自动重试 2 次4. 类装饰器了解即可除了函数Python 的类也可以作为装饰器核心是实现__call__魔术方法。这种方式常用于需要保存状态的场景比如计数器。classCountCalls:def__init__(self,func):self.funcfunc self.num_calls0# 状态保存在实例属性中def__call__(self,*args,**kwargs):self.num_calls1print(f函数{self.func.__name__}已被调用{self.num_calls}次)returnself.func(*args,**kwargs)CountCallsdefsay_hi():print(Hi!)say_hi()# 调用 1 次say_hi()# 调用 2 次 第二部分上下文管理器 (Context Managers)1. 什么是上下文管理器核心作用优雅且安全地管理资源的获取与释放。最典型的例子是打开文件。如果你忘记关闭文件会导致内存泄漏。上下文管理器配合with关键字可以保证无论代码是否发生异常资源都会被正确释放。只要一个对象实现了__enter__()和__exit__()方法它就是一个上下文管理器。# ❌ 没有上下文管理器容易忘记关闭或者中间报错导致没执行到 closefopen(test.txt,w)f.write(hello)f.close()# ✅ 有上下文管理器即使 write 报错文件也会自动关闭classFileManager:def__init__(self,filename,mode):self.filenamefilename self.modemodedef__enter__(self):print( 打开文件)self.fileopen(self.filename,self.mode)returnself.file# 这里的返回值会赋给 as 后面的变量 fdef__exit__(self,exc_type,exc_val,exc_tb):print( 关闭文件)ifself.file:self.file.close()# 注意如果有异常这里可以决定是否吞没异常withFileManager(test.txt,w)asf:f.write(Hello Context Manager!)2. contextlib.contextmanager简写语法每次写一个类并实现两个魔术方法太麻烦了。Python 提供了contextmanager装饰器让你用一个生成器函数就能快速创建上下文管理器。fromcontextlibimportcontextmanagercontextmanagerdefopen_file(filename,mode):print( 准备打开文件)fopen(filename,mode)try:# yield 之前的部分相当于 __enter__# yield 抛出的值就是 as 后面的变量yieldffinally:# yield 之后finally 块中相当于 __exit__# 无论有没有报错finally 都会执行print( 准备关闭文件)f.close()withopen_file(test.txt,r)asf:# do something...pass在 FastAPI 中的应用FastAPI 的依赖注入系统Depends大量使用这种yield语法来管理数据库会话Session。请求开始时创建 Session请求结束时关闭 Session。3. 异步上下文管理器FastAPI 高频使用在 FastAPI 这样的异步框架中我们连接的数据库、HTTP 客户端通常都是异步的。因此我们需要异步上下文管理器也就是配合async with使用。协议方法变成了__aenter__和__aexit__。简写装饰器变成了asynccontextmanager。importasynciofromcontextlibimportasynccontextmanager# 模拟一个异步的数据库连接asynccontextmanagerasyncdefasync_db_session():print( [开始] 创建异步数据库会话...)awaitasyncio.sleep(0.5)# 模拟网络延迟try:yieldDB_Session_Objectfinally:print( [结束] 关闭异步数据库会话...)awaitasyncio.sleep(0.5)asyncdefmain():# 使用 async withasyncwithasync_db_session()assession:print(f 正在使用:{session}执行查询...)# asyncio.run(main())在 FastAPI 中的应用LifespanFastAPI 允许你定义一个在 App 启动前执行、App 关闭后执行的代码块比如初始化数据库连接池这就是通过asynccontextmanager实现的。✏️ 练习题练习 1编写一个参数类型检查装饰器编写一个装饰器check_types它会在函数执行前检查传入的参数类型是否与函数签名的类型注解一致。如果不一致抛出TypeError。# 请实现 check_types 装饰器check_typesdefmultiply(a:int,b:int)-int:returna*b# multiply(2, 3) # 应该成功# multiply(2, 3) # 应该抛出 TypeError 参考答案fromfunctoolsimportwrapsimportinspectdefcheck_types(func):wraps(func)defwrapper(*args,**kwargs):# 获取函数的签名信息siginspect.signature(func)# 将传入的参数与签名绑定bound_argssig.bind(*args,**kwargs)bound_args.apply_defaults()forname,valueinbound_args.arguments.items():# 获取该参数的期望类型expected_typesig.parameters[name].annotationifexpected_typeisnotinspect._empty:ifnotisinstance(value,expected_type):raiseTypeError(f参数 {name} 期望类型{expected_type}但收到了{type(value)})returnfunc(*args,**kwargs)returnwrapper练习 2实现一个计时的异步上下文管理器编写一个类AsyncTimer配合async with使用在退出时打印代码块的执行耗时。 参考答案importtimeimportasyncioclassAsyncTimer:asyncdef__aenter__(self):self.starttime.time()print(异步计时开始...)returnselfasyncdef__aexit__(self,exc_type,exc_val,exc_tb):costtime.time()-self.startprint(f异步计时结束耗时:{cost:.4f}秒)# 测试# async def test():# async with AsyncTimer():# await asyncio.sleep(1) 关键概念总结卡片┌──────────────────────────────────────────────────────┐ │ 装饰器 (Decorators) 速查 │ ├──────────────────────────────────────────────────────┤ │ 本质接收函数并返回新函数的高阶函数。 │ │ 作用不改原代码增加新功能日志、鉴权、路由。 │ │ 强制规范必须在 wrapper 上加 wraps(func) 保留元信息。 │ │ 带参数装饰器需要三层嵌套工厂 - decorator - wrapper。 │ ├──────────────────────────────────────────────────────┤ │ 上下文管理器 (Context Managers) 速查 │ ├──────────────────────────────────────────────────────┤ │ 本质实现 __enter__ 和 __exit__ 的对象。 │ │ 作用配合 with 语句保证资源文件、连接必定被安全释放。 │ │ 快捷写法contextmanager yield 生成器。 │ │ 异步场景__aenter__ / __aexit__配合 async with。 │ │ 异步快捷asynccontextmanager async def yield。 │ └──────────────────────────────────────────────────────┘ 下一步学完本节后你已经补齐了所有的 Python 前置基础接下来你将正式进入第二阶段Web 后端基础知识。

相关文章:

1.3 装饰器与上下文管理器

📘 第一阶段 1.3 装饰器与上下文管理器学习目标:彻底掌握 Python 中用于代码复用和资源管理的高级特性,理解它们在 FastAPI 中的底层应用。 预计用时:2 天(每天约 3 小时) 重要程度:⭐⭐⭐⭐&a…...

百度网盘资源加速工具:突破下载限制的开源解决方案

百度网盘资源加速工具:突破下载限制的开源解决方案 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 如何在不升级会员的情况下实现百度网盘高速下载?这款…...

GHelper全面革新:华硕笔记本硬件控制的智能突破方案

GHelper全面革新:华硕笔记本硬件控制的智能突破方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar…...

PPTist:4大突破性功能重塑Web端演示文稿创作体验

PPTist:4大突破性功能重塑Web端演示文稿创作体验 【免费下载链接】PPTist PowerPoint-ist(/pauəpɔintist/), An online presentation application that replicates most of the commonly used features of MS PowerPoint, allowing for the…...

如何通过CyberpunkSaveEditor实现赛博朋克2077存档编辑与自定义体验?

如何通过CyberpunkSaveEditor实现赛博朋克2077存档编辑与自定义体验? 【免费下载链接】CyberpunkSaveEditor A tool to edit Cyberpunk 2077 sav.dat files 项目地址: https://gitcode.com/gh_mirrors/cy/CyberpunkSaveEditor 赛博朋克2077存档修改是许多玩家…...

回表为什么慢:二级索引到聚簇索引、覆盖索引与“延迟关联”

目标:你能把“回表”解释成一个可量化的成本模型,并掌握两类实战优化:覆盖索引与延迟关联(先查主键再回表)。1. 先把概念说透:InnoDB 的两棵树 聚簇索引(主键 B 树):叶子…...

Pixel Epic在MBA教学中的应用:学生用像素界面完成商业计划书作业案例

Pixel Epic在MBA教学中的应用:学生用像素界面完成商业计划书作业案例 1. 引言:当商业教育遇上像素冒险 在传统MBA教学中,商业计划书撰写往往是让学生头疼的作业任务。学生们需要花费大量时间收集数据、分析市场、构建财务模型,最…...

HarmonyOS 6学习:语音识别准确率提升与错误纠正方案

引言 在HarmonyOS 6应用开发中,语音识别能力已成为构建智能交互体验的核心技术。随着AI技术的快速发展,语音识别已广泛应用于教育、办公、智能家居等多个场景。然而,在实际开发过程中,开发者常面临一个普遍问题:语音识…...

HarmonyOS 6学习:Canvas实现圆角矩形进度条

在HarmonyOS应用开发中,进度条是展示任务进度、加载状态和数据可视化的重要组件。虽然系统提供了Progress组件,但在需要高度定制化、复杂视觉效果或特殊交互的场景下,开发者常常面临以下困境:样式限制:Progress组件难以…...

云服务器是如何保障数据安全的

在云服务器中,访问控制机制是重要的安全屏障。云服务商会实施严格的身份认证,用户需要通过密码、密钥、生物识别等多种方式进行身份验证,只有通过验证的用户才能获得相应的操作权限。同时,基于角色的访问控制将用户分配到不同角色…...

百考通:AI精准赋能开题报告,让学术研究全流程智能化

对于每一位学子与科研人而言,开题报告是学术研究的“第一粒扣子”,它不仅是研究方向的蓝图,更是顺利推进论文写作、获得导师认可的关键。然而,选题迷茫、文献梳理繁琐、逻辑框架搭建困难等问题,常常让开题之路步履维艰…...

2026最权威的十大降AI率助手推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 把维普平台针对 AI 生成内容的检测机制作为对象,要降低论文 AI 率得从语言重构以…...

「码动四季·开源同行」go实战案例:如何保证微服务实例资源安全?

今天我和你分享的是如何保证微服务实例资源安全的案例。在前文,我们实践了如何使用Go搭建一个基本的授权服务器,它的主要功能是颁发访问令牌和验证访问令牌的有效性。在统一认证与授权服务体系中,还存在资源服务器对用户数据进行保护&#xf…...

3个步骤掌握lx-music-desktop开源项目部署实践

3个步骤掌握lx-music-desktop开源项目部署实践 【免费下载链接】lx-music-desktop 一个基于 Electron 的音乐软件 项目地址: https://gitcode.com/GitHub_Trending/lx/lx-music-desktop lx-music-desktop是一款基于Electron开发的跨平台音乐软件,通过本指南你…...

别再把AI当聊天机器人了:Claude Code之父的“15倍速”工程化工作流全拆解

在这个AI编程工具层出不穷的时代,大多数人还在纠结“哪家大模型的代码补全更准”,或者在对话框里一行行地复制粘贴代码。然而,Anthropic工程师、Claude Code的缔造者Boris Cherny最近在X上公开的一套工作流,直接震碎了开发者社区的…...

禅道最新22.0+ 手动删除无法安装之清理卸载办法

禅道项目管理软件卸载方法详解:如何彻底清除所有相关文件和配置在企业或个人开发环境中,禅道(Zentao)作为一款广受欢迎的开源项目管理工具,因其功能全面、易用性强而被广泛使用。然而,在某些情况下&#xf…...

用Stacking集成学习算法实现精准预测

集成学习算法Stacking组合随机森林AdaBoost检验评估未来预测 Stacking 的原理是通过组合多个不同的学习模型,将它们的预测作为输入,训练一个元学习器来进行最终的预测 不同于 Bagging 和 Boosting,Stacking 的核心是使用一个新的模型来学习如…...

OpenClaw对话式编程:Qwen3-14B辅助代码生成与调试

OpenClaw对话式编程:Qwen3-14B辅助代码生成与调试 1. 为什么需要对话式编程助手 作为一个长期与代码打交道的开发者,我经历过太多深夜调试的煎熬时刻——盯着报错信息反复修改却始终无法通过测试,或是为了一个简单的功能翻遍Stack Overflow…...

AI辅助开发C语言项目,让快马平台智能生成学生成绩管理系统

最近尝试用AI辅助开发一个C语言的学生成绩管理系统,整个过程比想象中顺利很多。这个项目虽然不算复杂,但涉及模块化设计、文件操作、指针管理等知识点,正好可以验证AI在辅助开发中的实际效果。下面分享我的具体实践过程: 需求分析…...

【NotebookLM 使用教程】 Slides 指令库:11套通用PPT风格Prompt(含中英文对照)

前言适合谁:不想从零写提示词,想直接套用成熟的 PPT 风格结构。你会获得什么:11 套通用风格指令(英文为主,含中文备用),可直接粘贴到 NotebookLM Slides 的描述/自定义。建议阅读顺序&#xff1…...

基于Qwen3.5-2B的MySQL智能运维助手:自动SQL优化与故障排查

基于Qwen3.5-2B的MySQL智能运维助手:自动SQL优化与故障排查 1. 引言:当数据库运维遇上AI助手 最近跟几位DBA朋友聊天,发现他们每天要花大量时间处理两类重复性工作:分析慢SQL和排查数据库故障。一位在电商公司工作的朋友吐槽&am…...

基于YOLOv11深度学习的车辆碰撞检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)

一、项目介绍 随着城市交通密度的不断增加,交通事故尤其是车辆碰撞事件的频发对公共安全构成了严重威胁。传统的交通监控手段主要依赖人工查看监控视频,存在效率低下、实时性差以及容易因疲劳导致漏报等问题。 为了解决这一痛点,本项目基于…...

多语言双轨直销系统开发要点

系统架构设计 采用微服务架构确保模块化与扩展性,支持高并发场景。数据库设计需考虑多语言数据存储,推荐使用NoSQL(如MongoDB)处理非结构化翻译内容。负载均衡技术保障全球用户访问速度。核心功能模块 会员管理模块实现双轨层级计…...

基于STM32LXXX的无线收发芯片(CMT2300A-EQR)应用程序设计

一、简介: CMT2300A是一款超低功耗,高性能,适用于各种127至 1020 MHz无线应用的OOK,(G)FSK射频收发器。它是 CMOSTEK NextGenRFTM射频产品线的一部分,这条产品线 包含完整的发射器,接收器和收发器。CMT2300A的高集成 度,简化了系统设计中所需的外围物料。高达+20 dBm及-…...

黑客用ChatGPT生成病毒:安全测试员的噩梦

当攻击进入“自动化”时代对于软件测试从业者而言,每一次技术革新都意味着测试对象、方法和工具的深刻变革。过去,我们面对的是由人类程序员编写的、逻辑相对固定的代码。然而,大语言模型(LLM)的兴起,特别是…...

万象视界灵坛实战教程:构建语义搜索API供前端React/Vue应用调用

万象视界灵坛实战教程:构建语义搜索API供前端React/Vue应用调用 1. 项目概述与核心价值 万象视界灵坛是一款基于OpenAI CLIP模型的高级多模态智能感知平台,它将复杂的语义对齐技术转化为直观的视觉体验。本教程将指导开发者如何将其强大的语义搜索能力…...

短视频 SEO 关键词优化有哪些注意事项

短视频 SEO 关键词优化有哪些注意事项 在当今数字化时代,短视频平台已经成为了信息传播和内容分享的重要渠道。无论你是个人创作者还是品牌运营者,短视频的流量和曝光度都是关键。在这个竞争激烈的环境中,如何有效地进行短视频 SEO 关键词优…...

自学渗透测试第八天(网络安全法、伦理规范与工具链联动)

3.2 网络安全法、伦理规范与工具链联动(第8天)核心目标树立法律与道德意识:深入理解《网络安全法》等相关法规的核心要求,明确渗透测试的法律边界和职业伦理,建立红线意识。掌握标准测试流程:将前7天所学的…...

异步电机spwm变频仿真Matlab/simulink,三相逆变桥使用开关switch

异步电机spwm变频仿真Matlab/simulink,三相逆变桥使用开关switch在电力系统中,异步电机是一种非常重要的执行器,广泛应用于各种工业控制场景。而SPWM(空间相量调制)变频控制是一种高精度、高效率的调速控制方式&#x…...

Cursor Free VIP:彻底解决AI编程助手使用限制的智能解决方案

Cursor Free VIP:彻底解决AI编程助手使用限制的智能解决方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached yo…...