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

Python装饰器(自定义装饰器和3个内置装饰器)

目录

装饰器

函数作为参数

简单的装饰器

代参的装饰器

1. *args

2.**kwargs

💡 小贴士:使用 functools.wraps

Python内置装饰器

1.@property

2.@staticmethod

3.@classmethod

📌 类方法的特点:


装饰器

装饰器(Decorator) 是一种用于 修改或增强函数行为 的语法糖。它本质上是一个 接受函数作为参数并返回一个新函数的可调用对象(通常是函数或类)

特性

说明

装饰器本质

一个函数或类,接收函数并返回包装后的函数

语法

使用 @decorator

简化调用

参数支持

可以处理任意数量和类型的参数(使用 *args

**kwargs

多层装饰器

执行顺序是从内到外(最靠近函数的先执行)

保留函数元信息

推荐使用 functools.wraps

高级应用

类装饰器、带参数的装饰器、装饰器工厂等

函数作为参数

简单的装饰器

注:

箭头所指处是等价的

代参的装饰器

1. *args

  • 收集所有位置参数(positional arguments)。
  • 以元组形式保存。

2.**kwargs

  • 收集所有关键字参数(keyword arguments)。
  • 以字典形式保存。

同时使用两者来确保装饰器可以处理任意类型的参数

💡 小贴士:使用 functools.wraps

在写装饰器时,建议使用 from functools import wraps 来保留原函数的元信息(如文档字符串、名字等):

from functools import wrapsdef my_decorator(func):@wraps(func)def wrapper(*args, **kwargs):return func(*args, **kwargs)return wrapper

当你编写装饰器时,默认情况下会丢失被装饰函数的一些元信息(如函数名、文档字符串、注解等)。为了保留这些信息,可以使用 functools 模块中的 @wraps 装饰器。

没有使用 @wrapsadd 函数的元信息被覆盖了。

Python内置装饰器

1.@property

我们在此建立的内容将会被视作属性

内置装饰器,它允许你将一个方法“伪装”成属性访问,从而实现对属性的更精细控制(例如:封装、验证、延迟计算等),同时保持代码简洁易读。

在面向对象编程中,直接暴露实例变量可能会导致数据被随意修改,缺乏安全性。而通过方法来获取和设置属性又不够直观。@property 提供了一个优雅的中间方案:

  • 可以像访问属性一样调用方法(无需括号)
  • 可以在赋值时进行校验
  • 可以隐藏内部实现细节

访问时无需括号也不能被修改

2.@staticmethod

静态方法是一种属于类、但不依赖于类实例(也不需要 selfcls 参数)的方法。你可以通过类或实例来调用它,但它不会自动接收类或实例的引用。

静态方法的特点:

  • 不需要 selfcls 参数。
  • 可以直接访问类变量(但通常建议使用类名访问)。
  • 不能修改类或实例的状态(因为没有对 selfcls 的引用)。
  • 常用于工具函数、逻辑上与类相关但不需要实例化的方法。

这个方法可以被放在程序的任何位置,都不会影响这个类

我们在调用这个方法时不需要创造任何类

3.@classmethod

它将一个方法绑定到类而不是实例。与普通方法不同的是,类方法会自动接收类本身作为第一个参数(通常命名为 cls),而不是实例(self)。

📌 类方法的特点:

特点

说明

自动传入第一个参数

是,是类本身(约定为 cls

可否访问类属性

✅ 是

可否修改类属性

✅ 是

可否访问实例属性

❌ 否,因为没有 self

调用方式

可通过类或实例调用

类方法会影响整个类本身

http://www.lryc.cn/news/587008.html

相关文章:

  • Java 大视界 -- Java 大数据在智能教育学习资源智能分类与标签优化中的应用(346)
  • Java小白-线程 vs 虚拟线程,Java并发的新旧对决
  • 垃圾收集器-Serial Old
  • 教程:如何查看浏览器扩展程序的源码
  • 【操作系统-Day 5】通往内核的唯一桥梁:系统调用 (System Call)
  • 飞算 JavaAI 智能编程助手:颠覆编程旧模式,重构开发生态
  • 【Linux | 网络】应用层
  • 算法学习笔记:19.牛顿迭代法——从原理到实战,涵盖 LeetCode 与考研 408 例题
  • 在 Spring Boot 中使用 MyBatis 的 XML 文件编写 SQL 语句详解
  • 飞算JavaAI:开启 Java 开发 “人机协作” 新纪元
  • [Linux入门 ] RAID存储技术概述
  • [Dify]-基础入门6-Dify 的工作流 (Workflow) 详解(入门篇)
  • [Rust 基础课程]Hello World
  • Linux进程状态实战指南:转换关系、监控命令与状态解析
  • 二叉树算法详解和C++代码示例
  • Docker 快速上手
  • 深入理解 Linux 文件系统层级结构
  • 【Docker基础】Dockerfile指令速览:文件与目录操作指令详解
  • 【论文阅读】AdaptThink: Reasoning Models Can Learn When to Think
  • 系统思考:系统性抛弃
  • 深入解析Hadoop RPC:技术细节与推广应用
  • 【C++】优先队列简介与模拟实现 + 仿函数
  • 谷歌在软件工程领域应用AI的进展与未来展望
  • day5--上传视频
  • h() 函数
  • 现代Web开发实践:从零到全栈的高效率攻略
  • JAVA 反射总结
  • 从零开始跑通3DGS教程:(五)3DGS训练
  • lambdastream深入剖析
  • Dubbo-Admin 安装与使用指南:可视化管理 Dubbo 服务