【Python】Python 装饰器的用法总结

在 Python 中,装饰器(Decorator) 是一种设计模式,用于在不修改函数或类代码的情况下动态地扩展其功能。装饰器广泛应用于日志记录、性能监控、权限验证等场景,提供了一种简洁优雅的方式来“包裹”现有的代码。本文将介绍装饰器的基本概念、使用方式及常见场景。


1. 什么是装饰器?

装饰器是一个 高阶函数,它接受一个函数或类作为输入,并返回一个新的函数或类,通常用于增加额外的功能。通过装饰器,我们可以在不修改原始代码的情况下扩展函数或类的行为。装饰器的核心思想是 “包装”,它用来增强或修改目标函数或类的功能。

2. 装饰器的基本语法

装饰器的基本语法形式是:

@decorator_function
def target_function():pass

等价于:

def target_function():passtarget_function = decorator_function(target_function)

3. 创建一个简单的函数装饰器

函数装饰器的实现通常包含两个函数:一个是装饰器本身,另一个是“包装函数”。包装函数会在原始函数执行前后执行自定义逻辑。

示例:简单的日志装饰器
def log_decorator(func):def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")result = func(*args, **kwargs)print(f"Function {func.__name__} finished")return resultreturn wrapper@log_decorator
def say_hello(name):print(f"Hello, {name}!")say_hello("Alice")

输出:

Calling function: say_hello
Hello, Alice!
Function say_hello finished

解释:

  • log_decorator 是装饰器,它接收 say_hello 函数作为参数,返回一个新的函数 wrapperwrapper 在执行 say_hello 之前和之后打印日志。

4. 带参数的装饰器

装饰器本身可以带参数,这时需要增加额外的嵌套层级。这样可以让装饰器在使用时更加灵活。

示例:带参数的装饰器
def repeat_decorator(repeat_count):def decorator(func):def wrapper(*args, **kwargs):for _ in range(repeat_count):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator@repeat_decorator(repeat_count=3)
def say_hello(name):print(f"Hello, {name}!")say_hello("Alice")

输出:

Hello, Alice!
Hello, Alice!
Hello, Alice!

解释:

  • repeat_decorator 装饰器可以接受一个 repeat_count 参数,表示函数执行的次数。在 wrapper 函数中,调用目标函数多次。

5. 类装饰器

除了函数装饰器,Python 也支持类装饰器,用于修改或增强类的行为。

示例:类装饰器
def add_method(cls):def new_method(self):print("This is a new method")cls.new_method = new_methodreturn cls@add_method
class MyClass:def greet(self):print("Hello!")obj = MyClass()
obj.greet()      # 调用原方法
obj.new_method() # 调用新添加的方法

输出:

Hello!
This is a new method

解释:

  • add_method 装饰器给 MyClass 类添加了一个新的方法 new_method。通过 @add_method 装饰器,类 MyClass 被修改,新增了一个方法。

6. 使用 functools.wraps 保持原函数属性

当我们使用装饰器时,目标函数的元数据(如函数名、文档字符串等)会被包装函数覆盖。为了保留原函数的属性,我们可以使用 functools.wraps 装饰器。

示例:使用 wraps 保持元数据
from functools import wrapsdef log_decorator(func):@wraps(func)def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")return func(*args, **kwargs)return wrapper@log_decorator
def say_hello(name):"""Say hello to someone."""print(f"Hello, {name}!")print(say_hello.__name__)  # 输出函数的名字
print(say_hello.__doc__)   # 输出函数的文档字符串

输出:

say_hello
Say hello to someone.

解释:

  • 使用 @wraps(func) 保证了装饰器函数 wrapper 保留了原始函数 say_hello 的名字和文档字符串。

7. 常见应用场景

7.1 缓存结果(Memoization)

装饰器可以用于缓存函数的返回结果,避免重复计算,提升性能。

示例:缓存装饰器
def memoize(func):cache = {}def wrapper(*args):if args not in cache:cache[args] = func(*args)return cache[args]return wrapper@memoize
def slow_function(x):print(f"Computing {x}...")return x * xprint(slow_function(5))
print(slow_function(5))  # 缓存值,不会重复计算

输出:

Computing 5...
25
25
7.2 权限验证

装饰器常用于在执行函数前进行权限验证或用户身份检查。

示例:权限验证装饰器
def requires_permission(func):def wrapper(user, *args, **kwargs):if not user.get("is_admin", False):raise PermissionError("User does not have permission")return func(user, *args, **kwargs)return wrapper@requires_permission
def delete_user(user, username):print(f"Deleting user {username}")user = {"name": "Alice", "is_admin": False}
delete_user(user, "Bob")  # 抛出权限错误

8. 总结

装饰器是 Python 中的一项强大功能,能够让我们以非常简洁的方式在不改变原始代码的情况下增加功能。它们不仅适用于函数,也可以用于类、方法等。装饰器常常用于日志记录、缓存、权限验证等场景,在 Python 开发中十分常见。

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

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

相关文章

【C++】控制台小游戏

移动&#xff1a;W向上&#xff0c;S上下&#xff0c;A向左&#xff0c;D向右 程序代码&#xff1a; #include <iostream> #include <conio.h> #include <windows.h> using namespace std;bool gameOver; const int width 20; const int height 17; int …

「MATLAB」计算校验和 Checksum

什么是校验和 是一个算法&#xff0c;将一串数据累加&#xff0c;得到一个和。 MATLAB程序 function c_use Checksum(packet) %Checksum 求校验和 % 此处checksum提供详细说明checksum 0;for i 1:length(packet)value hex2dec(packet(i));checksum checksum value; …

JavaScript面试题之消息队列

JavaScript消息队列详解&#xff1a;单线程的异步魔法核心 在JavaScript的单线程世界中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步编程的核心机制&#xff0c;它像一位高效的调度员&#xff0c;让代码既能“一心多用”又避免卡顿。本文将深入剖析消…

京东外卖分润系统部署实操!0门槛入驻+全平台接入+自定义比例...这些人,赚翻了!

随着京东外卖的发展势头日渐迅猛&#xff0c;许多创业者们的态度也逐渐从原本的观望转变为了切实的行动&#xff0c;并开始通过各个渠道询问起了京东外卖自动分润系统部署相关的各项事宜&#xff0c;连带着以京东外卖自动分润系统质量哪家强为代表的多个问题&#xff0c;也成为…

【办公类-18-06】20250523(Python)“口腔检查涂氟信息”批量生成打印(学号、姓名、学校、班级、身份证、户籍、性别、民族)

背景需求: 6月是常规体检,前几天发了体检表(验血单),用Python做了姓名等信息的批量打印 【办公类-18-04】20250520(Python)“验血单信息”批量生成打印(学校、班级、姓名、性别)-CSDN博客文章浏览阅读969次,点赞19次,收藏11次。【办公类-18-04】20250520(Python)…

Python邮件处理:POP与SMTP

poplib简介 poplib 是Python 3中的官方邮件库&#xff0c;实现了POP的标准&#xff1a;RFC1939&#xff0c;用于邮件的收取。与之类似的还有imaplib 。 &#xff08;注&#xff1a;本文仅拿pop举例&#xff09; poplib的使用方法&#xff0c;就是几步&#xff1a; 先创建一…

IP风险度自检,多维度守护网络安全

如今IP地址不再只是网络连接的标识符&#xff0c;更成为评估安全风险的核心维度。IP风险度通过多维度数据建模&#xff0c;量化IP地址在网络环境中的安全威胁等级&#xff0c;已成为企业反欺诈、内容合规、入侵检测的关键工具。据Gartner报告显示&#xff0c;2025年全球78%的企…

Flink集成资源管理器

Flink集成资源管理器 Apache Flink 支持多种资源管理器&#xff0c;主要包括以下几种‌&#xff1a; YARN ResourceManager ‌&#xff1a;适用于使用 Hadoop YARN 作为资源管理器的环境。YARN ResourceManager 负责管理集群中的资源&#xff0c;包括 CPU、内存等&#xff0c;并…

upload 文件上传审计

目录 LOW Medium HIgh Impossible 概述 很多Web站点都有文件上传的接口&#xff08;比如注册时上传头像等&#xff09;&#xff0c;由于没有对上传的文件类型进行严格限制&#xff0c;导致可以上传一些文件&#xff08;比如Webshell&#xff09;。 上传和SQL、XSS等都是主流…

【freertos-kernel】list

freertos list 基本类型结构体ListItem_t &#xff08;list.h&#xff09;List_t &#xff08;list.h&#xff09; 宏函数函数vListInitialisevListInitialiseItemvListInsertEndvListInsertuxListRemove 基本类型 freertos为了兼容性&#xff0c;重新定义了基本类型&#xff…

游戏盾的功有哪些?

游戏盾的功能主要包括以下几方面&#xff1a; 一、网络攻击防护 DDoS攻击防护&#xff1a; T级防御能力&#xff1a;游戏盾提供分布式云节点防御集群&#xff0c;可跨地区、跨机房动态扩展防御能力和负载容量&#xff0c;轻松达到T级别防御&#xff0c;有效抵御SYN Flood、UD…

PycharmFlask 学习心得:路由(3-4)

对路由的理解&#xff1a; 用户输入网址 例如&#xff1a;http://localhost:5000/hello 浏览器会向这个地址发起一个 HTTP 请求&#xff08;比如 GET 请求&#xff09; 请求到达 Flask 的服务器 Flask 监听着某个端口&#xff08;如 5000&#xff09;&#xff0c;收到请求后…

课程与考核

6.1 课程讲解与实战考核 6.1.1 SQL注入篇考核 考核目标&#xff1a;通过手动注入与工具结合&#xff0c;获取目标数据库敏感信息。 题目示例&#xff1a; 目标URL&#xff1a;http://vuln-site.com/product?id1 要求&#xff1a; 判断注入类型&#xff08;联合查询/报错注…

线程池介绍,分类,实现(工作原理,核心组成,拒绝策略),固态线程池的实现+详细解释(支持超时取消机制和不同的拒绝策略)

目录 线程池 介绍 分类 实现 工作原理 核心组成 拒绝策略 固态线程池 功能 std::future 实现 拒绝策略支持 提交任务 超时取消 用户检测取消 安全销毁 代码 测试 线程池 介绍 线程池(图解,本质,模拟实现代码),添加单例模式(懒汉思路代码)_线程池单例-CSDN博…

纺线机与PLC通讯故障?ETHERCAT/CANopen网关秒解协议难题

在纺织行业智能化转型浪潮中&#xff0c;设备间高效通信是实现自动化生产的关键。JH-ECT009疆鸿智能EtherCAT转CANopen协议转换网关&#xff0c;凭借出色的协议适配能力&#xff0c;成功架起倍福PLC与自动纺线机间的通信桥梁&#xff0c;为纺织厂自动化生产注入强劲动力。 纺织…

深度剖析并发I/O模型select、poll、epoll与IOCP核心机制

核心概要&#xff1a;select、poll、epoll 和 IOCP 是四种用于提升服务器并发处理能力的I/O模型或机制。前三者主要属于I/O多路复用范畴&#xff0c;允许单个进程或线程监视多个I/O流的状态&#xff1b;而 IOCP 则是一种更为彻底的异步I/O模型。 一、引言&#xff1a;为何需要这…

microsoft中word如何添加个人签名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入签名图片 图片格式选择裁剪合适的大小 使用的签名如果不是白色纸张的话可以重新着色 依次点击图片格式——颜色——重新着色——黑白50% 设置透…

linux初识--基础指令

Linux下基础指令 ls 指令 语法&#xff1a; ls [ 选项 ] [ ⽬录或⽂件 ] 功能&#xff1a;对于⽬录&#xff0c;该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件&#xff0c;将列出⽂件名以及其他信 息。 常⽤选项&#xff1a; -a 列出⽬录下的所有⽂件&#xff0c;包括以…

实战:Dify智能体+Java=自动化运营工具!

我们在运营某个圈子的时候&#xff0c;可能每天都要将这个圈子的“热门新闻”发送到朋友圈或聊天群里&#xff0c;但依靠传统的实现手段非常耗时耗力&#xff0c;我们通常要先收集热门新闻&#xff0c;再组装要新闻内容&#xff0c;再根据内容设计海报等。 那怎么才能简化并高…

RabbitMQ可靠传输——持久性、发送方确认

一、持久性 前面学习消息确认机制时&#xff0c;是为了保证Broker到消费者直接的可靠传输的&#xff0c;但是如果是Broker出现问题&#xff08;如停止服务&#xff09;&#xff0c;如何保证消息可靠性&#xff1f;对此&#xff0c;RabbitMQ提供了持久化功能&#xff1a; 持久…