233饿13 发表于 2015-12-18 08:58:23

Python装饰器

#装饰器
#应用场景:当需为写好的函数添加新功能时,既不让你修改原函数,又不让你修改调用函数的方式

#例1
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
#使用functools装饰器装饰
#函数是有几个特殊属性比如函数名,在被装饰后,上例中的函数名foo会变成包装函数的名字wrapper,
#它能将装饰过的函数的特殊属性保留。
#在上例中print(foo.__name__) #被修饰后foo的函数名变为wrapper
import functools
def timeit(func):
        @functools.wraps(func) #加装饰器
        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__ #函数名还是之前的函数名foo

#上述例子虽然已满足需求但是如果被装饰的函数有参数怎么办
#例3
def w1(func):
        def inner(*args,**kwargs): #可处理多参数的装饰器
                #添加验证
                func(*args,**kwargs)
                #添加功能
                return func(*args,**kwargs)
        return inner
@w1
def f1(arg1,arg2,arg3):
        return (arg1,arg2,arg3)
print f1(1,2,3)

#多个装饰器装饰一个函数
#例4
def w1(func):
        def inner(*args,**kwargs):
                # 验证1
                func(*args,**kwargs)
                # 验证3
                return func(*args,**kwargs)
        return inner

def w2(func):
        def inner(*args,**kwargs):
                # 验证1
                func(*args,**kwargs)
                # 验证3
                return func(*args,**kwargs)
        return inner
@w1
@w2
def f1(arg1,arg2,arg3):
        print 'f1'

#多层装饰器
#例5
def Before(request,kargs):
    print 'before'

def After(request,kargs):
    print 'after'

def Filter(before_func,after_func):
    def outer(main_func):
      def wrapper(request,kargs):
            before_result = before_func(request,kargs)
            if(before_result != None):
                return before_result

            main_result = main_func(request,kargs)
            if(main_result != None):
                return main_result

            after_result = after_func(request,kargs)
            if(after_result != None):
                return after_result
      return wrapper
    return outer
@Filter(Before, After)
def Index(request,kargs):
    print 'index'

页: [1]
查看完整版本: Python装饰器