https://blog.csdn.net/try_test_python/article/details/80802199

前几天在学装饰器的时候,关于装饰器内层函数调用目标函数时是否return目标函数的调用产生了一点迷惑,事实是当被装饰的目标函数有返回值的时候,装饰器内层函数也必须返回该目标函数的调用。

我们都知道不带括号的函数名指向是函数代码所在的内存地址,加上括号之后就变成了一个执行命令,那么这个‘func( )’到底有什么意义呢?

上面这张图可以大概看出点东西,单独的函数名是 function类的一个实例对象,而函数名() 则没有任何类型,是个无类型。

然后看这张图,一个无返回值的函数调用指向的内存地址和 ‘None’的内存地址是同一个,说明什么呢,说明函数名()很可能也是个变量。那这个变量里面装的什么东西呢,从上面两张图可以看得出,它里面什么也没有。

同样的,print()作为解释器自带的函数同样也指向了空。

这三张图想说明什么呢,可能有点乱,但是结论也很清楚,func()仅仅是告诉系统要执行其函数名指向的那段代码,剩下的没有别的意义,任何函数名加上括号,那就是执行的信号,告诉系统,我要执行。(其实任何可调用类型都是这样)

然后开始进入关于return的一些研讨。

在装饰器里,闭包的内层函数对目标函数的处理是否return,结果很不一样。

先看上面这块代码,当函数往外有返回值的时候,func()的指向就不一样了,它此时指向的是返回值所在的内存地址,我们上面已经得到了一些结论,那就是函数没有返回值的时候,func()是空的,有了返回值,那么它就成了指向返回值的这么个变量。所以,func()除了作为执行代码的信号之外,还用来保管函数的返回值。

我们可以理解为,func()是一个容纳函数运行附加值的容器,return的作用就是将这个附加值往外传递,传递给谁呢,传递给func()这个变量。下面做个小实验:

如上图所示,return将函数的返回值赋值给所在的“函数名()”,而函数名()这个变量也因为所装载的数据而改变了类型:

如图,func1()的类型变成了整型。

也就是说,如果一个函数有了结果而不往外传递这个结果的话,那么这个结果就算是被丢弃了,作为这个函数的‘首席’接受者,函数名()将仅仅是函数运行的一道代表命令的字符,除此之外,什么也不是。

现在讨论装饰器中return的必要性。

上面三张图分别是未经过装饰器扩展时目标函数的执行结果,然后是加了装饰器,但是没有返回函数结果和返回了函数结果的三种情况。

我们知道,装饰器的作用就是给目标函数扩展功能,基本原则是不能影响原函数的功能,所以不加return的话,原函数的基本功能都受到影响了,必须对原函数的返回值进行再次return。

现在我们来说结论,函数名是指代的函数代码所在的空间,函数名加括号,指代的是函数往外传递的数据,而return就是往外传递数据的工具,如果函数名()没有接收到return出来的数据,那么“函数名()”除了执行命令外,什么也不是,函数往外传递的数据就丢失了。

装饰器的核心在于闭包的内层函数,外层函数将目标函数拿来加工,用内层函数包裹目标函数的代码,然后将这一整块代码返回给目标函数的函数名,现在目标函数的函数名(代号func)指向的是加工过的函数代码,原来的代码成了外来户,所以原来代码传递的数据如果没有中间人进行传递的话,func将不能接收那个数据,那个数据就丢失了。func()原来可以容放原函数返回值,现在就什么都没有了。所以,return是很有必要的。
---------------------  
作者:haiton大人  
来源:CSDN  
原文:https://blog.csdn.net/try_test_python/article/details/80802199?utm_source=copy  
版权声明:本文为博主原创文章,转载请附上博文链接!

关于Python装饰器内层函数为什么要return目标函数的一些个人见解的更多相关文章

  1. 使用python装饰器计算函数运行时间的实例

    使用python装饰器计算函数运行时间的实例 装饰器在python里面有很重要的作用, 如果能够熟练使用,将会大大的提高工作效率 今天就来见识一下 python 装饰器,到底是怎么工作的. 本文主要是 ...

  2. Python 装饰器 property() 函数

    描述:property() 函数的作用是在新式类中返回属性值. @property 装饰器简单理解就是负责把一个方法变成属性调用 下面理解property()方法语法: class property( ...

  3. Python装饰器(函数)

    闭包 1.作用域L_E_G_B(局部.内嵌.全局...): x=10#全局 def f(): a=5 #嵌套作用域 def inner(): count = 7 #局部变量 print a retur ...

  4. Python装饰器、内置函数之金兰契友

    装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...

  5. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  6. python装饰器1:函数装饰器详解

    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...

  7. Python 带参数的装饰器 [2] 函数参数类型检查

    在Python中,不知道函数参数类型是一个很正常的事情,特别是在一个大项目里.我见过有些项目里,每一个函数体的前十几行都在检查参数类型,这实在是太麻烦了.而且一旦参数有改动,这部分也需要改动.下面我们 ...

  8. Day11 Python基础之装饰器(高级函数)(九)

    在python中,装饰器.生成器和迭代器是特别重要的高级函数   https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...

  9. python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

随机推荐

  1. Android ListView使用BaseAdapter与ListView的优化 (转至 http://www.open-open.com/lib/view/open1339485728006.html)

    在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作.也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点.读者可 ...

  2. MySQl安装全解

    这是第二次安装MySql了.第一次安装花了几个小时,理解安装的每一个页面,这次光寻找安装包就找了几个.因此感觉有必要做一次全面的安装笔记.(有点浪费时间了,可是感觉非常值得)本人系统是window7. ...

  3. socket client简单传输数据

    1.整数转换为用于TCP传输的二进制 _host = "127.0.0.1" _port = 5678 _address = (_host, _port) s=socket.soc ...

  4. perl 实现ascall 码转换

    今天需要在perl中实现一个字母表, 总不能把26个字母一个一个写出来,于是查资料,可以利用ascii码转换把数字转换成对应的字母 chr函数可以利用ascii编码把数字转换成对应的字母 perl - ...

  5. 内网DNS投毒技术劫持会话

    工具列表: tcpdump Ferret Hamster node closurether 拓扑环境: 攻击机:Kali 10.10.10.237 被攻击机: win7 10.10.10.232 因为 ...

  6. v$Session详解

    从Oracle10gR1开始,Oracle在V$SESSION中增加关于等待事件的字段,实际上也就是把原来V$SESSION_WAIT视图中的所有字段全部整合到了V$SESSION视图中,开始的时候我 ...

  7. 改善C#程序的建议4:C#中标准Dispose模式的实现

    http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个 ...

  8. GLSL/C++ 实现滤镜效果

    入门效果之浮雕 "浮雕"图象效果是指图像的前景前向凸出背景.常见于一些纪念碑的雕刻上.要实现浮雕事实上很easy.我们把图象的一个象素和左上方的象素进行求差运算.并加上一个灰度.这 ...

  9. 九度 1529:棋盘寻宝(递推DP)

    题目描述: 现在有一个8*8的棋盘,上面放着64个价值不等的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于1000),一个人的初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应 ...

  10. 静态变量数组实现LRU算法

    LRU算法的解释详情请见 https://baike.baidu.com/item/LRU/1269842 这里百度百科给出的比较详细,然后后面有一个例子 说 LRU(least recently u ...