python装饰器

python装饰器学习笔记

有一个函数say

def say():
   return "Hello"

现在需要得到下面的结果

'<b>Hello</b>'

一般可能会这样做

def makebold(string):
   return "<b>"+string+"</b>"
print makebold(say())

这样的嵌套用多了会让代码看起来很杂乱,并且在某些特别的情况下,如django的view中,我不能把view放到一个函数里来执行,这样的就可以使用装饰器来实现这个结果。

装饰器函数

import functools
def makebold(func):
   @functools.wraps(func)
   def wrapper(*args):
       return "<b>" + func(*args) + "</b>"
   return wrapper

给hello函数加上装饰器

@makebold
def hello():
   return "Hello"

只需要调用hello就能实现在嵌套的效果

hello()     ## 返回 '<b>Hello</b>'

如果我现在不要固定只在输出外面加<b>标签,需要给参数来决定外面的标签

def  makestyle(text):
   def decorator(func):
       @functools.wraps(func)
       def wrapper(*args):
           return '<%s>%s</%s>' % (text, func(*args) , text)
       return wrapper
   return decorator

带参数的装饰器

@makestyle('i')
def hello():
   return "Hello World"

调用hello函数

hello()     ## 返回 '<i>Hello</i>'

带参数的装饰器的执行相当于

print makestyle('i')(hello)

先执行makestyle(‘i’),返回decorator函数,再调用decorator函数,参数是hello函数,最终返回wrapper函数。

因为最后返回的是wrapper函数,函数名字是’wrapper’,所以需要用Python内置的functools.wraps来把原始函数的__name__等属性复制到wrapper()函数中,不然有些依赖函数签名的代码执行就会出错了。

anyShare分享到:

《python装饰器》有1个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注