最近在看廖雪峰老师的关于装饰器的教程, 写的非常好,链接:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000#0
1. 函数是可作为变量传递的。
import datetime
def now():
print datetime.datetime.now()
f = now()
f()
>>> 2016-05-05 17:03:47.370000
2. 不带参数的装饰器
@functools.wrap()函数把原始函数的name等属性复制到wrapper()函数中,
否则,有些依赖函数签名的代码执行就会出错
#定义装饰器
import datetime
import functools
def log(func):
@functools.wrap(func)
def wrapper(*args, **kwrags):
print 'call %s' % func.__name__
return func(*args, **kwrags)
return wrapper
@log
def now():
print datetime.datetime.now()
>>> call now()
>>> 2016-05-05 17:03:47.370000
3 带参数的装饰器
def log(text):
def decorator(func):
@functools.wrap(func)
def wrapper(*args, **kwrags):
print '%s %s' %s(text, func.__name__)
return func(*args, **kwrags)
return wrapper
return decorator
@log('Hangzhou')
def now():
print datetime.datetime,now()
>>> Hangzhou now
>>> 2016-05-05 17:03:47.370000
4. 练习实现一个能在函数调用的前后打印出'begin call'和'end call'的日志。
def call_print(func):
@functools.wrap(func)
def wrapper(*args, **kwrags):
print '%s begin call' % func.__name__
res = func(*args, **kwrags)
print '%s end call' % func.__name__
return res
return wrapper
@call_print
def now():
print datetime.datetime.now()
>>> now begin call
>>> 2016-05-05 17:03:47.370000
>>> now end call
5 编写一个即支持带参数的修饰器 又支持不带参数的修饰器
def call_print(text):
if callable(text):
@functools.wrap(func)
def wrapper(*args, **kwrags):
print '%s begin call' % func.__name__
res = func(*args, **kwrags)
print '%s end call' % func.__name__
return res
return wrapper
else:
def decorator(func):
@functools.wrap(func)
def wrapper(*args, *kwrags):
print '%s begin call' % func.__name__
res = func(*args, **kwrags)
print '%s end call' % func.__name__
return res
return wrapper
return decorator
@log
def now():
print datetime.datetime.now()
@log('Hangzhou')
def now():
print datetime.datetime.now()
>>> now begin call
>>>2016-05-05 17:03:47.370000
>>> now end call
>>> Hangzhou begin call
>>> 2016-05-05 17:03:47.370000
>>> Hangzhou end call
**************
#装饰器带参数,并且包装函数带参数
def deco(arg):
def _deco(func):
def __deco(*args, **kwargs):
print('befor %s called [%s].' % (func.__name__, arg))
ret = func(*args, **kwargs)
print('after %s called [%s].' % (func.__name__, arg))
return ret
return __deco
return _deco
@deco('mymodule')
def myfunc(a, b):
print('myfunc() called.')
return a+b
print myfunc(10, 199)
参考
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
网友评论