今天将python的decorator系统地学习了一下,自己也试着写了下,共有三种类型,第一种是普通装饰器,不带参数也不带返回值的。只需要将func(*args, **kwargs)在闭包函数块儿里执行就行,这是一定要执行的,不然就会返回与原来函数没有任何关系的函数了,甚至报错。同时如果是用decorator,那么原来函数的函数名字就变成了wrapper
的名字,这时,需要我们将原来的和wrapper的函数名字对调过来才行,如用@wrap(func)或者是return functools.update_wrapper(wrapper, func)这样的语句将其调换过来,这样函数的名字就和原来的一模一样了,不会再以后的使用中出错。有参数的decorator,就是多了一层嵌套,最外面的是传入参数的函数,里面嵌套原来的不带参数的decorator,最后将那个decorator返回就行。最后是被装饰的函数有返回值的情况,将func的结果赋值给result, 最后将result返回出去即可。下面是自己讲各种情况都试了下的代码,自己当笔记。
的名字,这时,需要我们将原来的和wrapper的函数名字对调过来才行,如用@wrap(func)或者是return functools.update_wrapper(wrapper, func)这样的语句将其调换过来,这样函数的名字就和原来的一模一样了,不会再以后的使用中出错。有参数的decorator,就是多了一层嵌套,最外面的是传入参数的函数,里面嵌套原来的不带参数的decorator,最后将那个decorator返回就行。最后是被装饰的函数有返回值的情况,将func的结果赋值给result, 最后将result返回出去即可。下面是自己讲各种情况都试了下的代码,自己当笔记。
# __author__ = 'lulongfei'
from functools import wraps
import functools
'''
common decorator no args no return result
'''
def my_decortor(func):
@wraps(func)
def wrapper(*args, **kwargs):
print ('Calling decorated function')
return func(*args, **kwargs)
return wrapper
@my_decortor
def example():
'''Docstring'''
print ('Called example function')
example()
example.__name__
'''
decorator have args
'''
def log(text):
def decorator(func):
def wrapper(*args, **kwargs):
print '%s%s():'%(text, func.__name__)
return func(*args, **kwargs)
return wrapper
return decorator
@log('my_decorator:')
def example():
'''Docstring'''
print ('Called example function')
example()
def spamdef(fn):
def wrapper(*args):
print "spam, spam, spam"
return fn(*args)
return wrapper
@spamdef
def useful(a, b):
print a**2 + b**2
useful(3, 4)
def arg_sayer(what):
def what_sayer(meth):
def new(self, *args, **kwargs):
print what
return meth(self, *args, **kwargs)
return new
return what_sayer
def FooMaker(word):
class Foo(object):
@arg_sayer
def say(self):pass
return Foo()
foo1 = FooMaker('this')
foo2 = FooMaker('that')
print type(foo1)
foo1.say()
def flaz(self):return 'flaz'
def flam(self):return 'flam'
def change_method(new):
'''waring: only decorate the __new__() method with this decorator'''
if new.__new__ != '__new__':
return new
def __new__(cls, *args, **kwargs):
cls.flaz = flaz
cla.flam = flam
if hasattr(cls, 'say'):del cls.say
return super(cls.__class__, cls).__new__(cls, *args, **kwargs)
return __new__
class Foo(object):
@change_method
def __new__():pass
def say(self):print 'Hi me:', self
foo = Foo()
print foo.flaz()
foo.say()
'''decortor include the return result'''
def printdebug(func):
def decorator(user):
print ('enter the login')
result = func(user)
print ('exit the login')
return result
return decorator
@printdebug
def login(user):
print ('in login:' + user)
msg = "success" if user == "chuck" else "bruno"
return msg
result1 = login("chuck")
print result1
python的装饰器在编程里使用时,可以高效地减少一些重复的工作。
参考文章:
http://www.ibm.com/developerworks/cn/linux/l-cpdecor.html
http://www.cnblogs.com/jerry-Chou/archive/2012/05/23/python-decorator-explain.html
感谢机器猫的文章