理解python中的装饰器

装饰器可以改变目标函数的行为,而不用更改目标函数本身,可以扩展原来函数的行为。

1. 在说明什么是装饰器之前,先要理解python中的函数

Python中的函数是一等公民:
- 函数可以赋给变量
- 在函数中定义其他函数
- 函数可以作为参数传递
- 函数可以作为其他函数的返回值
- 内层函数可以获取闭包(closure)中的数据

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")

# <p>Outputs lorem ipsum, John dolor sit amet</p>

3. Python装饰器的语法

Python提供了以上代码的简洁化语法(syntactic sugar)。我们只需在目标函数之前生命装饰器的名字即可(前面加上@

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")

# Outputs <p>lorem ipsum, John dolor sit amet</p>

现在我们来给目标函数再加两个装饰器,加上<div>, <strong>标签

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

如果不用python提供的简介语法,我们需要这样写:

get_text = div_decorate(p_decorate(strong_decorate(get_text)))

但是有了python装饰器语法,表达式就变得好看多了:

@div_decorate
@p_decorate
@strong_decorate
def get_text(name):
   return "lorem ipsum, {0} dolor sit amet".format(name)

print get_text("John")

# Outputs <div><p><strong>lorem ipsum, John dolor sit amet</strong></p></div>

注:装饰器是有顺序的,顺序不同会产生不同的结果

可以给wrapper传入 args and *kwargs作为参数,这样它就可以接受任意数目的参数了:

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()

4. 向装饰器传参

给装饰器再加一层外层函数,用来接受参数并返回装饰器

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")

# Outputs <p>Hello John</p>

参考资料:
https://www.thecodeship.com/patterns/guide-to-python-function-decorators/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值