ITPub博客

首页 > 应用开发 > IT综合 > python装饰器

python装饰器

IT综合 作者:biggerl 时间:2015-04-14 17:28:14 0 删除 编辑
'''
装饰器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/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: python模块random
请登录后发表评论 登录
全部评论

注册时间:2014-10-24

  • 博文量
    39
  • 访问量
    96957