首页 > 编程语言 >【Python】- 装饰器

【Python】- 装饰器

时间:2023-09-01 15:24:18浏览次数:36  
标签:函数 Python add result 装饰 decorator numbers

装饰器

通过一个简单的装饰器示例来展示装饰器的特性及本质:
python_decorator.py

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function is called")
        result = func(*args, **kwargs)  # 调用原始函数
        print(f'func result is {result}')
        print("After function is called")
        result= 20
        return result
    return wrapper

@my_decorator
def add_numbers(a, b):
    print('running now add_numbers()')
    return a + b

result = add_numbers(3, 5)
print("Result:", result)

我们可以根据这段代码的运行流程来查看装饰器的特性:
在这里我们需要使用到https://pythontutor.com/render.html#mode=display这个网站。该网站可以一步一步的输出整段代码的运行流程

1、在加载模块时,可以看到第一步会先执行my_decorator这个装饰器函数的定义。然后将其存储在内存中。注意:这里是因为装饰器函数与被装饰器函数定义在同一个模块,Python会从上到下将变量或函数的定义保存到内存中,装饰器的实际执行的第一步应该是@my_decorator这部分。

2、随后会执行@my_decorator部分,这部分其实是将add_numbers()这个被装饰的函数作为参数传递给my_decorator(func)这个装饰器函数。

3、然后进入my_decorator装饰器函数,会执行wrapper()这个内部函数的定义。然后return wrapper函数对象。

4、result = add_numbers(),调用 add_numbers() 被装饰函数时,实际会跳转到装饰器函数 my_decorator return的内部函数 wrapper() 中。然后开始执行 wrapper() 这个内部函数,

5、result = func(*args, **kwargs) , 在 wrapper() 这个内部函数中调用了原始函数,也就是 add_numbers() 这个函数。然后将 add_numbers() 的return赋值给result这个变量。这时result的值为3+5=8。随后又将20赋值给result这个变量并进行返回。

6、print("Result:", result) 当正常运行add_numbers()函数时,本来应该是输出3+5=8的,但是因为装饰器的原因,运行add_numbers()函数时实际进入的是装饰器中的返回的内部函数wrapper(),而在内部函数wrapper()中我将result的结果修改为20,所以无论参数传的是多少,最后的resut都将是20。

从整个装饰器的运行流程以及最后返回的结果来看。可以很清晰的总结出装饰器的本质以及作用:

装饰器的定义:

  • 装饰器的本质就是一个包裹函数,用来修改或者增强被装饰的函数。
  • 装饰器是一种可调用对象,它的参数是被装饰的函数。
  • 装饰器可能会对被装饰的函数做相关处理,然后再返回该函数。或者会将被装饰的函数替换为另外一个函数或可调用对象。

装饰器的特性:

  • 装饰器是一个函数或者一个可调用对象。
  • 装饰器可以把被装饰的函数替换为其他的函数。
  • 装饰器会在所在模块被加载时运行。

标签:函数,Python,add,result,装饰,decorator,numbers
From: https://www.cnblogs.com/white-kitty/p/17671971.html

相关文章

  • 一个python 类 通常有哪几部分组成
    一个Python类通常包含以下几个部分:类的声明:使用class关键字来声明类,后跟类名称和一个冒号。初始化方法__init__:定义一个特殊的方法__init__来初始化对象,并设置初始属性值。这个方法在创建对象时自动调用。属性:定义类的属性(变量),可以是类属性或实例属性,以及它们的默......
  • Lnton羚通视频分析算法平台OpenCV-Python教程 图像变换(频域变换)
     频域变换是一种将信号从时间域表示转换为频率域表示的方法。它可以帮助我们理解信号的频率成分以及进行信号处理和分析。常见的频域变换方法包括傅里叶变换(FourierTransform)和离散傅里叶变换(DiscreteFourierTransform,DFT)。以下是它们的简要介绍:傅里叶变换(FourierTransform):......
  • Python下载_Python免费版下载「编程工具」中文版介绍
    Python具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用。Python的名字来源于一个喜剧,也许最初设计Python这种语言的人并没有想到今天它会在工业和科研上获得如此广泛的使用。著名的自由软件作者EricRaymond在他的文章《如何成为一名黑客》中,将Python列为黑客应当学习的......
  • Python-3.10.5学习笔记
     Linux系统-部署-运维系列导航pip源初始化pipconfigsetglobal.index-urlhttps://pypi.tuna.tsinghua.edu.cn/simplepipconfigsetinstall.trusted-hostpypi.tuna.tsinghua.edu.cn VSCode插件安装语法检查flake8代码格式化yapf文件及文件夹图标vscode-icon......
  • Python-嵌套数组获取对应的值
    二维数组示例:er_array=[['霹雳火','急先锋','超音速']]forinner_arrayiner_array:#嵌套二维数组,使用两个嵌套的for循环遍历数组并获取值forvalueininner_array:print(value) 方法一:使用enumerate函数,遍历获取元素的索引er_array=[['霹雳......
  • Python 深度学习目标检测评价指标
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • python字典的应用一(增删改查)
    #一.有如下字典内容用程序解答下面的题目dic={'python':95,'java':99,'c':100}#1.字典的长度是多少print(len(dic))#2.请修改'java'这个key对应的value值为98dic["java"]=98print(dic)#3.删除c这个keydeldic["c"]print(di......
  • Python中while的and和or
    whileAandB:同时满足A和B条件whileAorB:满足A或B任意一条以1768.交替合并字符串官方答案为启发,以前没意识到while还可以用and和or。其实无论用什么,只要看最后的结果是True或FalseclassSolution:defmergeAlternately(self,word1:str,word2:str)->str:......
  • python f-string
    python|f-string_cuckooman的博客-CSDN博客>>>a='hello'>>>b=12.23456>>>f'{a}''hello'>>>F'{a}'#f支持大写和小写混用'hello'>>>f'{a=}'#直接以a=的形式打印......
  • Python的替换和切割
    strip()用法:.strip()是字符串方法之一,在Python中用于移除字符串开头和结尾的空白字符(包括空格、制表符\t、换行符\n等)。这个方法返回一个新的字符串,原始字符串本身不会被修改。下面是.strip()方法的用法示例:s="你好,我叫周杰伦"s1=s.strip()print(s1......