我最近开始学习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()函数如何调用返回函数名称的装饰器感到困惑。
答案 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
。