Python学习笔记——decorator

 学习参考资料:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000

小结:1.请编写一个decorator,能在函数调用的前后打印出'begin call''end call'的日志。

import functools
def log(f):
    @functools.wraps(f)
    def wrapper(*args,**kw):
        print 'begin call'
        return f(*args,**kw)
    print 'end call'
    return wrapper
@log
def f():
    print 'Function is processing'

结果:开始前会打印begin call 但是结束后不会有end call。分析原因:在return f(*args,**kw)语句时对应的f函数就已经返回(执行完毕),而打印'end call'只在第一次(初始化log(f)的时候)时执行了,而后每次调用f()都不执行该语句。解决办法暂时没找到。

----------------------------------------------------------------------------------------------------------------------------------------

找到了解决办法  语句return f(*args,**kw)实际是先运算f() 再返回得到的值,所以只需写成

val = f(*args,**kw)

print 'end call'

return val

就可以啦!

----------------------------------------------------------------------------------------------------------------------------------------

2.能否写出一个@log的decorator,使它既支持:

@log
def f():
    pass

又支持:

@log('execute')
def f():
    pass

import functools
def log(text):
    if type(text) == str:
        def decorator(f):
            @functools.wraps(f)
            def wrapper(*args,**kw):
                print '%s "%s"'%(f.__name__,text)
                return f(*args,**kw)
            return wrapper
        return decorator
    else:
        f = text
        @functools.wraps(f)
        def wrapper(*args,**kw):
            print '%s'%(f.__name__)
            return f(*args,**kw)
        return wrapper

写的略复杂,没想出来还能不能再精简了。传入参数后先判断实参类型来区别是log(f)还是log('execute')(f),从而确认是三层嵌套还是两层嵌套的装饰器。

你可能感兴趣的:(Python学习)