关于python 的@操作符 Decorator 的用法
来源:互联网 发布:centos php服务器搭建 编辑:程序博客网 时间:2024/05/16 04:59
简单的说,@操作符是用来提供调用的,光是说明可能无法理解,写了一个小小的例子:
def f1(arg):
print "f1"
rl = arg()
print rl
return rl + "f1"
@f1
def f2(arg = ""):
print "f2"
return arg + "f2r"
print "start"
print f2
#print f2("1") 出错
#print f1(None)
这个例子是我自己一边改一边写的,和想像中有很大的区别,不过倒是认为完美的解释了这个操作符的原理:
以上语句在运行会输出
f1
f2
f2r
start
f2rf1
按ptyhon自带说明, 这里@符作符相当于 f1(f2()) 。但是从输出可以看出,这个运算其实在开始 import 时就已经在执行了,这也就是 f1 f2 f2r这几行会在 start 之前就出现的原因。
而当运行到代码时,其实 f2函数已经不存在了, f2 在这里已经变成一个字符串了, 这就是后面 #print f2("1") 会出错的原因,
也就是说,实际上前面那些个 @ 操作符完成了这么一个操作:
f2 = f1(f2())
f2已经被覆盖为 f1(f2) 的返回值了。运行时f2的结果已经固化,使用参数也不会重新计算,或者说根本无法使用参数。
当然原理如此,如果真的这么用,这东西当然就没有多少用处了。
但是我们假如定义一个类作为 装饰符 的话。
class myDecorator(object):
def __init__(self, f):
print "inside myDecorator.__init__()"
self.f = f
def __call__(self):
print "inside myDecorator.__call__()"
self.f()
@myDecorator
def aFunction():
print "inside aFunction()"
print "Finished decorating aFunction()"
aFunction()
以上,初始化时 aFunction 会变成myDecorator类的一个实例,通过重载()操作符的办法,这样子aFunction实际上就变成了myDecorator.()操作了。于是从外型上看,这还是一个普通的函数的调用,但其实暗地里你可以做出很多不为人知的操作的……。
或者如果不想使用类,也可以使用内部函数的办法。如下的代码和上面的同样的效果
def entryExit(f):
def new_f():
print "Entering", f.__name__
f()
print "Exited", f.__name__
return new_f
@entryExit
def func1():
print "inside func1()"
理论知道了,扩展开来,这东西能用来做什么呢?好吧,只有想不到的,没有做不到的。
以下页面列出了很多用这东西做出来的功能
http://wiki.python.org/moin/PythonDecoratorLibrary
比如:记忆函数,cached,自动为类加上属性,输出函数的参数,性能分析器,同步,替换函数的实现,状态机(同样的函数调用会产生不同的结果,甚至会调用完全不相干的代码)……
我认为其中最好的一个实现就是这个 Another Retrying Decorator ,一个可以对函数进行自动延时重试,并忽略掉指定异常的函数。
在网络操作中经常需要处理各种异常,并且需要进行重试的,现在只要在想要这么做的函数前加上 @retries(3) 就完美的解决了,连代码都不需改,真的是太方便了。
def f1(arg):
@f1
def f2(arg = ""):
print "start"
print f2
#print f2("1") 出错
#print f1(None)
这个例子是我自己一边改一边写的,和想像中有很大的区别,不过倒是认为完美的解释了这个操作符的原理:
以上语句在运行会输出
f1
f2
f2r
start
f2rf1
按ptyhon自带说明, 这里@符作符相当于 f1(f2()) 。但是从输出可以看出,这个运算其实在开始 import 时就已经在执行了,这也就是 f1 f2 f2r这几行会在 start 之前就出现的原因。
而当运行到代码时,其实 f2函数已经不存在了, f2 在这里已经变成一个字符串了, 这就是后面 #print f2("1")
也就是说,实际上前面那些个 @ 操作符完成了这么一个操作:
f2 = f1(f2())
f2已经被覆盖为 f1(f2) 的返回值了。运行时f2的结果已经固化,使用参数也不会重新计算,或者说根本无法使用参数。
当然原理如此,如果真的这么用,这东西当然就没有多少用处了。
但是我们假如定义一个类作为 装饰符 的话。
class myDecorator(object):
@myDecorator
def aFunction():
print "Finished decorating aFunction()"
aFunction()
以上,初始化时 aFunction 会变成myDecorator类的一个实例,通过重载()操作符的办法,这样子aFunction实际上就变成了myDecorator.()操作了。于是从外型上看,这还是一个普通的函数的调用,但其实暗地里你可以做出很多不为人知的操作的……。
或者如果不想使用类,也可以使用内部函数的办法。如下的代码和上面的同样的效果
def entryExit(f):
@entryExit
def func1():
理论知道了,扩展开来,这东西能用来做什么呢?好吧,只有想不到的,没有做不到的。
以下页面列出了很多用这东西做出来的功能
http://wiki.python.org/moin/PythonDecoratorLibrary
比如:记忆函数,cached,自动为类加上属性,输出函数的参数,性能分析器,同步,替换函数的实现,状态机(同样的函数调用会产生不同的结果,甚至会调用完全不相干的代码)……
我认为其中最好的一个实现就是这个 Another Retrying Decorator ,一个可以对函数进行自动延时重试,并忽略掉指定异常的函数。
在网络操作中经常需要处理各种异常,并且需要进行重试的,现在只要在想要这么做的函数前加上 @retries(3) 就完美的解决了,连代码都不需改,真的是太方便了。
0 0
- 关于python 的@操作符 Decorator 的用法
- 关于python 的@操作符 Decorator 的用法
- 关于Python 的@操作符 Decorator 的用法
- 关于python 的@操作符 (Decorator) 的用法
- Python:decorator的使用
- python 的decorator
- Python的@符号 --decorator
- 【Python】decorator的作用
- Python的decorator使用
- python decorator的理解
- 关于decorator 的理解
- Python中@的用法(Decorator:装饰器)
- python中decorator的用法及原理(一)
- 关于python decorator找到的一篇比较好的文章
- Python的装饰器(decorator)
- Python的decorator学习笔记
- Python Decorator 的来龙
- Python的装饰器decorator
- 异步任务
- 【C语言】模拟实现memmove函数(考虑内存重叠)
- 猜猜看-二
- 链表的插入操作总结
- 小米11.11:海量数据压力下的推送服务
- 关于python 的@操作符 Decorator 的用法
- h5-localstorage-购物车
- Java常用排序算法
- NSRange类详解
- 在工作线程中刷新主界面控件状态的方法小结
- 关于七牛异步转码出现no such bucket 问题
- hibernate : No positional parameters in query 错误解决办法
- 在Windows下用C++扩展PHP
- iOS开发小技巧之--WeakSelf宏的进化