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

【Python】装饰器在装什么

装饰器decorator,可以简单的说 是一个输入参数是函数,返回值也是函数的一个函数

在Python中,函数是什么?

在讲decorator之前,我们要先理清楚python的一些基础知识。第一件事就是函数是什么。可能有些人知道在python中的所有东西都是对象,都是object,函数也不例外。函数只是Python中的一个普通的object而已。函数对象具有可调用性(callable),可以在程序中像其他对象一样被传入其他函数或作为返回值。

函数对象在Python中如何使用?

函数对象可以在Python中像普通变量一样被传入其他函数,并且可以作为返回值返回一个新的函数。例如,可以定义一个接受两个参数的函数,然后将它作为参数传递给另一个函数,并在该函数内部调用这个参数函数。

什么是decorator,它如何运作?

装饰器(decorator)是Python中的一个特殊语法糖,它本身是一个可调用的对象(callable)(通常是函数),可以用来修改其他函数的行为。
使用装饰器时,它会接收一个函数作为输入,并返回一个新的函数作为输出,这个新函数通常会实现一些额外的功能,比如计时、日志记录等。

import time
# 计时callable
def timeit(f):def wrapper(x):start =  time.time()ret = f(x)print(time.time() - start)return retreturn wrapper
@timeit
def my_func(x):time.sleep(x)
my_func(1)
  • 不太好理解?我们想象一下,其实这就等价于

my_func(1)
→ 实际调用 timeit(my_func)(1)
→ 执行 wrapper(1)
→ 在 wrapper 中:
1. 记录开始时间
2. 调用原 my_func(1)
3. 打印耗时
4. 返回 my_func 的结果

装饰器中的 wrapper是一个闭包,关于闭包朋友们可以看看此篇:【Python】闭包是什么包?闭包的底层实现机制-CSDN博客

装饰器是否只能用于单参数的函数?

装饰器不仅限于单参数函数,它可以用于任何数量参数的函数。通过使用*args**kwargs,即变长函数参数,装饰器能够适应不同参数数量的函数。

import time
# 计时callable
def timeit(f):def wrapper(*args, **kwargs):start =  time.time()ret = f(*args, **kwargs)print(time.time() - start)return retreturn wrapper@timeit
def add(x,y):return x + yprint(add(2,3))

是否存在带参数的装饰器?

带参数的装饰器在本质上也是通过增加一层函数调用来实现的。它首先计算带有参数的装饰器,并得到一个返回函数的新装饰器,然后用这个新装饰器去装饰目标函数,最终得到的结果是一个带有额外功能(由装饰器提供的)的新函数。

类装饰器这个词在不同场景下有什么不同的含义?类装饰器如何实际应用并起到装饰作用?

类装饰器这个词在不同环境下具有不同含义:

  • 可以当做装饰器使用的类
  • 能够装饰类的装饰器

这两个概念是正交的,一个是关于装饰器本身,另一个是关于装饰器要装饰的对象。类装饰器的应用示例中,将一个名为Timer的类作为装饰器应用在add函数上。通过类装饰器,原本的add函数被转换为一个Timer类的对象,并将add函数作为参数传递给Timer类的实例,从而实现对add函数的行为进行包装和扩展。

类装饰器是否可以传递参数,如何实现?

类装饰器同样可以传递参数。例如,当需要在打印的时间前加上自定义前缀时,可以通过在装饰器中接收参数并在调用类实例时将这些参数传递给目标函数来实现。

如何理解装饰器语法糖背后的等价形式?

装饰器语法糖的等价形式是指,对于一个类作为装饰器的情况,可以理解为:

  1. 类对象被实例化
  2. 将目标函数作为参数传入类的实例中
  3. 最终得到一个可调用的对象

该对象执行时会先执行原函数,再添加额外的行为(如计时等)。

真正的类装饰器是如何工作的?

真正的类装饰器是一个输入是类、返回也是类的函数,它通过重载类的字符串表示(如__str__方法),在不改变原有类定义的前提下,对类的行为进行修改。这样,任何自定义类只需添加此类装饰器,就能方便地打印出类中数据成员的信息,有助于调试和理解类的行为。

http://www.xdnf.cn/news/5188.html

相关文章:

  • [ctfshow web入门] web70
  • 《深入理解Linux网络》笔记
  • MySQL的Order by与Group by优化详解!
  • [docker基础四]容器虚拟化基础之 LXC
  • Visual Studio Code 前端项目开发规范合集【推荐插件】
  • 单片机-STM32部分:10-1、485
  • 【AI提示词】漏斗思维优化专家
  • RocketMQ Kafka区别
  • upload-labs靶场通关详解:第四关
  • zdir3个人网盘dockerfile打包
  • 202534 | KafKa简介+应用场景+集群搭建+快速入门
  • 大模型微调终极方案:LoRA、QLoRA原理详解与LLaMA-Factory、Xtuner实战对比
  • 绑定 SSH key(macos)
  • uniapp-商城-49-后台 分类数据的生成(方法加精)
  • 【计算机视觉】OpenCV实战项目:FunnyMirrors:基于OpenCV的实时哈哈镜效果实现技术解析
  • Checkmk实战指南:从零构建企业级监控系统
  • 字节:增强LLM角色区分能力
  • 第十八章,入侵检测/防御系统(IDS/IPS)
  • mysql-8.0.30-winx64 Install/Remove of the Service Denied!
  • 互联网大厂Java求职面试实战:Spring Boot微服务与数据库优化详解
  • Java云原生到底是啥,有哪些技术
  • DA14585墨水屏学习
  • 电子电器架构 --- 新能源高压上下电那点事一文通
  • 浅谈装饰模式
  • 旅游推荐数据分析可视化系统算法
  • 数据结构中的栈与队列:原理、实现与应用
  • C++学习-入门到精通-【6】指针
  • 【AI智能推荐系统】第七篇:跨领域推荐系统的技术突破与应用场景
  • [RoarCTF 2019]Easy Calc1
  • 【许可证】Open Source Licenses