Python学习笔记——decorator

来源:互联网 发布:sqlserver 完美 卸载 编辑:程序博客网 时间:2024/05/02 12:53

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

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

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

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

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

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

val = f(*args,**kw)

print 'end call'

return val

就可以啦!

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

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

@logdef f():    pass

又支持:

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

importfunctools
def log(text):
    iftype(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),从而确认是三层嵌套还是两层嵌套的装饰器。

0 0
原创粉丝点击