在本文中我们主要介绍什么是函数装饰器?如何使用它?
1、关于函数我们需要知道这些
在正式进入装饰器之前,我们需要知道python中函数都可以干嘛。
可以将函数赋给变量:
def greet(name):
return "hello "+name
greet_someone = greet
print greet_someone("John")
可以在函数内部再定义函数:
def greet(name):
return "hello "+name
greet_someone = greet
print greet_someone("John")
可以将函数作为参数传递:
def greet(name):
return "Hello " + name
def call_func(func):
other_name = "John"
return func(other_name)
print call_func(greet)
可以将函数作为参数返回:
def compose_greet_func():
def get_message():
return "Hello there!"
return get_message
greet = compose_greet_func()
print greet()
2、函数装饰器
函数装饰器就是将以上所提到的全部放在一起:
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
my_get_text = p_decorate(get_text)
print my_get_text("John")
3、python中的函数装饰器
当然,在python中我们不需要通过"my_get_text = p_decorate(get_text)"来获取装饰器,python提供了专门用于装饰器的语法,我们只需要使用@操作符告诉python解释器我们使用什么函数来装饰我们的函数即可:
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
@p_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
我们还可以使用多个装饰器来装饰一个函数:
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def strong_decorate(func):
def func_wrapper(name):
return "<strong>{0}</strong>".format(func(name))
return func_wrapper
def div_decorate(func):
def func_wrapper(name):
return "<div>{0}</div>".format(func(name))
return func_wrapper
@div_decorate
@p_decorate
@strong_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
我们也可以用装饰器来装饰类方法:
def p_decorate(func):
def func_wrapper(*args, **kwargs):
return "<p>{0}</p>".format(func(*args, **kwargs))
return func_wrapper
class Person(object):
def __init__(self):
self.name = "John"
self.family = "Doe"
@p_decorate
def get_fullname(self):
return self.name+" "+self.family
my_person = Person()
print my_person.get_fullname()
装饰器还可以有自己的参数:
def tags(tag_name):
def tags_decorator(func):
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
print get_text("John")
以上实现的装饰器会改变函数对象本身的属性,如:
print get_text.__name__
以上调用的输出是“func_wrapper",事实上get_text的函数对象的__name__,__doc__,__mudole__等都被装饰函数覆盖了,为了不被覆盖,我们可以使用functools.wraps这个装饰器。如:
from functools import wraps
def tags(tag_name):
def tags_decorator(func):
@wraps(func)
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
"""returns some text"""
return "Hello "+name
print get_text.__name__ # get_text
print get_text.__doc__ # returns some text
print get_text.__module__ # __main__
本文仅仅只是简单的装饰器介绍,更详尽的内容可以参考:
https://wiki.python.org/moin/PythonDecoratorLibrary