请仔细看我们的decorator实例。我们定义了一个接受单个参数some_func的名为outer的函数。在outer内部我们定义了一个名为inner的嵌套函数。inner函数打印一个字符串然后调用some_func,在#1处缓存它的返回值。some_func的值可能在每次outer被调用时不同,但是无论它是什么我们都将调用它。最终,inner返回some_func的返回值加1,并且我们可以看到,当我们调用存储于#2处decorated里的返回函数时我们得到了输出的文本和一个返回值2而不是我们期望的调用foo产生的原始值1.
我们可以说decorated变量是foo的一个“装饰”版本——由foo加上一些东西构成。实际上,如果我们写了一个有用的decorator,我们可能想用装饰后的版本来替换foo,从而可以得到foo的“增添某些东西”的版本。我们可以不用学习任何新语法而做到这一点——重新将包含我们函数的变量进行赋值:>>> foo = outer(foo)
>>> foo # doctest: +ELLIPSIS
现在任何对foo()的调用都不会得到原始的foo,而是会得到我们经过装饰的版本!领悟到了一些decorator的思想吗?
10、装饰器的语法糖--@符号(The @ symbol applies a decorator to a function)
Python 2.4通过在函数定义前添加一个@符号实现对函数的包装。在上面的代码示例中,我们用一个包装了的函数来替换包含函数的变量来实现了包装。>>> add = wrapper(add)
这一模式任何时候都可以用来包装任何函数,但是如果们定义了一个函数,我们可以用@符号像下面示例那样包装它:>>> @wrapper
... def add(a, b):
... return Coordinate(a.x + b.x, a.y + b.y)
请注意,这种方式和用wrapper函数的返回值来替换原始变量并没有任何不同,Python只是增添了一些语法糖(syntactic sugar)让它看起来更明显一点。
11、*args and **kwargs
我们已经写了一个有用的decorator,但是它是硬编码的,它只适用于特定种类的函数——带有两个参数的函数。我们函数内部的checker函数接受了两个参数,然后继续将参数闭包里的函数。如果我们想要一个能包装任何类型函数的decorator呢?让我们实现一个在不改变被包装函数的前提下对每一次被包装函数的调用增添一次计数的包装器。这意味着这个decorator需要接受所有待包装的任何函数并将传递给它的任何参数传递给被包装的函数来调用它(被包装的函数)。
这种情况很常见,所以Python为这一特性提供了语法支持。请确保阅读Python Tutorial以了解更多,但是在函数定义时使用*运算符意味着任何传递给函数的额外位置参数最终以一个*作为前导。因此:>>> def one(*args):
... print args # 1
>>> one()
()
>>> one(1, 2, 3)
(1, 2, 3)
>>> def two(x, y, *args): # 2
... print x, y, args
>>> two('a', 'b', 'c')
a b ('c')
第一个函数one只是简单的将任何(如果有)传递给它的位置参数打印出来。正如你在#1处见到的,在函数内部我们只是引用了args变量——*args只是表明在函数定义中位置参数应该保存在变量args中。Python也允许我们指定一些变量并捕获到任何在args变量里的其它参数,正如#2处所示。
*运算符也可以用于函数调用中,这时它也有着类似的意义。在调用一个函数时带有一个以*为前导的变量作为参数表示这个变量内容需要被解析然后用作位置参数。再一次以实例来说明:>>> def add(x, y):
... return x + y
>>> lst = [1, 2]
>>> add(lst[0], lst[1]) # 1
3
>>> add(*lst) # 2
3
#1处的代码抽取出了和#2处相同的参数——在#2处Python为我们自动解析了参数,我们也可以像在#1处一样自己解析出来。这看起来不错,*args既表示当调用函数是从一个iterable抽取位置参数,也表示当定义一个函数是接受任何额外的位置变量。
当我们引入**时,事情变得更加复杂点,与*表示iterables和位置参数一样,**表示dictionaries & key/value对。很简单,不是么?>>> def foo(**kwargs):
... print kwargs
>>> foo()
{}
>>> foo(x=1, y=2)
{'y': 2, 'x': 1}
更多:python lock一步步教你理解Python装饰器
https://www.002pc.comhttps://www.002pc.com/python/818.html
你可能感兴趣的Python,一步步,装饰,理解
mysql 查出数据一对多python使用unittest测试接口步奏详解
这次给大家带来python使用unittest测试接口步奏详解,python使用unittest测试接口的注意事项有哪些,下面就是实战案例,一起来看一下。
win7开始菜单 图标只需两步实现Windows7系统自动拨号
第一步:建立拨号连接
我们新建一个宽带连接(开始->控制面板->网络和Internet->查看网络状态和任务》设置新的连接或网络-> 连接到 Internet->
互联网公司项目总监制造业网络发展势头较好 张峰四点提议助力下一步持续发展
《互联网公司项目总监制造业网络发展势头较好 张峰四点提议助力下一步持续发展》总结了关于学习电脑教程,对于我们来sfk8网确实能学到不少知识。飞象网讯(九月/文中)现阶段,一连
gta5手机互联网连接七星基本上该系统星图布署已完成 迈进南北全世界关键性一步
七星四号基本上该系统星图布署圆满完成,我国七星迈进从国外南北国际性、从区域内南北全世界的“关键性一步”。“七
互联网 旅游 实习IMT-2020(5S)前进两组追加两个专家组:车联网成为下一步重点项目
sfk8网认为此文章对《互联网 旅游 实习IMT-2020(5S)前进两组追加两个专家组:车联网成为下一步重点项目》说的很在理。
linux 命令查看用户教你三步修改linux 主机名
修改 Linux 主机名需要3步。电脑技术002pc网认为此文章对《linux 命令查看用户教你三步修改linux 主机名》说的很在理,第二电脑
怎么dos硬盘安装xpwindowsXP 20步详细配置
XP配置20步,申精!
1.察看本地共享资源 运行CMD输入net share,如果看到有异常的共享,那么应该关闭。但是有时你关闭共享下次开机的时候又出现了,那么你应该考虑一下,你
家庭接入互联网2018年dSIM卡不会跑到哪一步?
飞象网讯(两匹大友/文)1月底2日消息,dSIM卡早在2011年就被提到,新技术持续发展没问题,也是一个较为准确的趋势。但走到3S、穿过4S,5S也要来了,eSIM新技术一直没推展起来。这个完全
怎么给电脑安装字体手动搭建属于自己的博客 -- 第一步
本来想搞点幽默又不失水平的开场白,敲了一行字果断删了,我果然不适合写点啥,咱还是干实事吧!
今年暑假8月份在家闲着没事,就想搭建一个个人博客看看,前前后后花了大概2-3天吧,毕竟
0踩
赏
0 赞