'''
装饰器decorator
转自:http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
'''
'''
1装饰器入门
'''
import time
def foo():
start = time.clock()
print('in foo()')
end=time.clock()
print('used:',end-start)
foo()
'''
单独做一个计时函数,将foo的引用传递给他,以不变应万变,不用修改foo函数或者copy代码了
'''
def timeit(func):
start=time.clock()
func()
end=time.clock()
print('used:',end-start)
timeit(foo)
'''
原本我们是这样调用的:foo(),修改以后变成了:timeit(foo)。这样的话,如果foo在N处都被调用了,你就不得不去修改这N处的代码。或者更极端的,考虑其中某处调用的代码无法修改这个情况,比如:这个函数是你交给别人使用的。既然如此,我们就来想想办法不修改调用的代码;如果不修改调用代码,也就意味着调用foo()需要产生调用timeit(foo)的效果。我们可以想到将timeit赋值给foo,但是timeit似乎带有一个参数……想办法把参数统一吧!如果timeit(foo)不是直接产生调用效果,而是返回一个与foo参数列表一致的函数的话……就很好办了,将timeit(foo)的返回值赋值给foo,然后,调用foo()的代码完全不用修改!
'''
import time
def foo():
print('in foo()')
def timeit(func):
def wrapper():
start=time.clock()
func()
end=time.clock()
print('used:',end-start)
return wrapper
foo=timeit(foo)
foo()
'''
这样,一个简易的计时器就做好了!我们只需要在定义foo以后调用foo之前,加上foo = timeit(foo),就可以达到计时的目的,这也就是装饰器的概念,看起来像是foo被timeit装饰了。在在这个例子中,函数进入和退出时需要计时,这被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming)。与传统编程习惯的从上往下执行方式相比较而言,像是在函数执行的流程中横向地插入了一段逻辑。在特定的业务领域里,能减少大量重复代码。
'''
'''
2、python 额外支持
'''
'''
1.语法糖,上面这段代码看起来似乎已经不能再精简了,Python于是提供了一个语法糖来降低字符输入量。
'''
import time
def timeit(func):
def wrapper():
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
return wrapper
@timeit #在定义上加上这一行与另外写foo = timeit(foo)完全等价
def foo():
print 'in foo()'
foo()
'''
2.内置装饰器
内置的装饰器有三个,分别是staticmethod、classmethod和property,作用分别是把类中定义的
实例方法变成静态方法、类方法和类属性。
'''
'''
3、functools
functools模块提供了两个装饰器。
1‘wraps(wrapped[, assigned][, updated]):
函数是有几个特殊属性比如函数名,在被装饰后,上例中的函数名foo会变成包装函数的名字wrapper,如果你希望使用反射,可能会导致意外的结果。这个装饰器可以解决这个问题,它能将装饰过的函数的特殊属性保留。这个装饰器带有一个参数,可选参数assigned中的属性名将使用赋值的方式替换,而updated中的属性名将使用update的方式合并,你可以通过查看functools的源代码获得它们的默认值。对于这个装饰器,相当于wrapper = functools.wraps(func)(wrapper)
'''
import time
import functools
def timeit(func):
@functools.wraps(func) #如果注释这一行,foo.__name__将是'wrapper'。
def wrapper():
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
return wrapper
@timeit
def foo():
print 'in foo()'
foo()
print foo.__name__
'''
2.total_ording(cls):
它的作用是为实现至少__lt__、__le__、__gt__、__ge__其中一个的类加上其他的比较方法,这是一个类装饰器。
'''
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29974949/viewspace-1575915/
,如需转载,请注明出处,否则将追究法律责任。