在编写ryu应用程序时候,发现源代码中有许多python装饰器,类似如下:
@set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
def _port_status_handler(self, ev):
msg = ev.msg
reason = msg.reason
port_no = msg.desc.port_no
ofproto = msg.datapath.ofproto
if reason == ofproto.OFPPR_ADD:
self.logger.info("port added %s", port_no)
elif reason == ofproto.OFPPR_DELETE:
self.logger.info("port deleted %s", port_no)
elif reason == ofproto.OFPPR_MODIFY:
self.logger.info("port modified %s", port_no)
else:
self.logger.info("Illeagal port state %s %s", port_no, reason)
网上查阅资料学习一些相关说明,写一些自己的理解思路,以runoob中的代码为例:
def a_new_decorator(a_func):
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")
a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell"
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
我们知道python中函数可以作为一个函数的参数,也可以作为一个函数的返回值使用,装饰器中既用一个函数作为参数,同时又把一个函数作为返回值。
分析已经被装饰的a_function_requiring_decoration()的执行过程,可以看到被装饰的a_function_requiring_decoration()是由a_new_decorator()生成的,函数体定义wrapTheFunction()的同时返回,执行被装饰的a_function_requiring_decoration()的内容就相当于执行wrapTheFunction(),于是先打印,再执行未被装饰的a_function_requiring_decoration(),最后再打印。
@a_new_decorator
def a_function_requiring_decoration():
"""Hey you! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")
a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()
#the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
@a_new_decorator就相当于是一种简便的写法罢了。