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

【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__方法),在不改变原有类定义的前提下,对类的行为进行修改。这样,任何自定义类只需添加此类装饰器,就能方便地打印出类中数据成员的信息,有助于调试和理解类的行为。

关于作者

  • CSDN 大三小白新手菜鸟咸鱼本科生长期更新强烈建议不要关注

更多 Python 小节

  • 【Python】一直搞不懂迭代器是个啥。。-CSDN博客
  • 【Python】包了一个闭包,Python解释器偷偷干了什么-CSDN博客
  • 【Python|面试】import用了无数次,但你不知道它的一切……-CSDN博客

相关文章:

  • 递归函数(斐波那契数列0,1,1,2,3,5,8,13,21,34,55...)
  • 运放OP方向技术要点和大厂题目解析
  • LWIP的IP协议笔记
  • Java中的代理机制
  • STC32G12K128程序大于64KB使用128KB用户EEPROM设置
  • JavaWeb基础
  • 438. 找到字符串中所有字母异位词(滑动窗口)
  • Android方法耗时监控插件开发
  • vue3项目中CodeMirror的复杂用法,实现自定义语法模式,手动在指定光标位置插入/获取/替换/绑定文本
  • 当可视化遇上 CesiumJS:突破传统,打造前沿生产配套方案
  • CentOS7.9部署FunASR实时语音识别接口 | 部署商用级别实时语音识别接口FunASR
  • 线程安全 1_线程安全
  • Java Bean容器详解:核心功能与最佳使用实践
  • 关于单片机的基础知识(一)
  • Qt/C++开发监控GB28181系统/实时视频预览/视频点播/rtp解包解码显示
  • M0基础篇之ADC
  • 树莓派4的v4l2摄像头(csi)no cameras available,完美解决
  • leetcode0829. 连续整数求和-hard
  • python:vars()方法
  • [docker基础四]容器虚拟化基础之 LXC
  • 用社群活动维系“不开发”古镇的生命力
  • 央行:5月8日起,下调个人住房公积金贷款利率0.25个百分点
  • 抗战回望20︱《山西省战区抗敌行政工作检讨会议议决案》:“强民政治”、“说服行政”
  • 吴清:加强监管的同时传递监管温度,尽力帮助受影响企业应对美加征关税的冲击
  • 潘功胜:央行将创设科技创新债券风险分担工具
  • 央视热评:从银幕到生活,好故事如何“撬动”大市场