如何在Python中使用装饰器

时间:2014-11-18 00:57:56

标签: python decorator python-decorators

我最近开始学习Python中的装饰器,并发现以下一段令我困惑的代码。

HANDLERS = {}

def handler_for(template):
    def decorator(f):
        HANDLERS[template] = f
        return f
    return decorator

def get_template(template, **kwargs):
    #This function got me all confused. How does HANDLERS.get(template, None) works and how does it return demo_func() function?
    return HANDLERS.get(template, None)

def email(template, **kwargs):
    handler = get_template(template, **kwargs)
    contents = handler(**kwargs)
    print contents

@handler_for('demo')
def demo_func(**kwargs):
    #Do something and return the String

if __name__ == "__main__":
    email('demo')

我尝试使用Python Debugger进行调试,但我仍然对get_template()函数如何调用返回函数名称的装饰器感到困惑。

1 个答案:

答案 0 :(得分:0)

  

我尝试使用Python Debugger进行调试,但我仍然对get_template()函数如何调用返回函数名称的装饰器感到困惑。

嗯......事实并非如此。您使用@handler_for('demo')调用装饰器。

装饰者并不像看起来那么复杂,一旦你记住以下内容是等价的:

@beans
def spam(eggs):
    print(eggs)

def spam(eggs):
    print(eggs)
spam = beans(spam)

beans不一定只是一个标识符,它可以(几乎)任何表达式,甚至是函数调用。所以,你的代码是这样做的:

demo_func = handler_for('demo')(demo_func)

handler_for'demo'作为其template参数的值。然后它定义并返回一个本地函数decorator。因此,当它被调用时,它可以访问自己的参数f,也可以访问构造时的封闭template值。该函数立即调用demo_func作为其f值,它只是隐藏HANDLERS字典中的函数并将其保持不变。所以,内联一切:

def demo_func(**kwargs):
    #Do something and return the String
template = 'demo'
HANDLERS[template] = demo_func
demo_func = demo_func

所以,因为get_template只是在HANDLERS中查找内容,当您稍后调用get_template('demo')时,它会找到demo_func