之前的一篇日志提到POX中Event的监听方法,不过内容基本上是从代码注释中翻译过来的。通过这种publisher/subscriber的模式,可以实现事件触发后调用多个函数/子程序的功能。但是这就会有一个问题:调用顺序,也就是优先级。

对POX看的代码不多,在l3、l2的app中都没有看到定义。然而,事件系统部分的函数定义中,却有优先级字段的定义:

def addListener (self, eventType, handler,<br /> once=False, weak=False, priority=None, byName=False):

上面的代码是第一种监听方式的函数定义。参数中包含了priority选项。而第二种定义方法写的则要曲折一些。首先是listento函数:

def listenTo (self, source, *args, **kv):<br /> return autoBindEvents(self, source, *args, **kv)

然后就看到了返回的autoBindEvents函数。

def autoBindEvents (sink, source, prefix='', weak=False, priority=None):
这个函数只需要看定义就可以了,这是最终绑定Event和Listener的函数。【还是要忍不住吐槽一下,python实在是好用啊~零基础改+写代码完全无压力。只需要看看一些语法的定义就好了~于是,看一下之前的定义里面有一个比较重要的语法,就是对于“*args, **kv”的定义。

*args和**kwargs着两个特殊语法在函数定义是用来传递一个不定长的参数列表。单个星号(*args)用于传递非keyworded,可变长度参数列表,而两个星号(**kwargs)则用于传递keyworded形式可变长度的参数列表。下面举例说明单个星号参数是如何传递非keyworded形式参数:(例子中传递一个位置参数,以及两个不定长的参数):
<br /> def test_var_args(farg, *args):<br /> print "formal arg:", farg<br /> for arg in args:<br /> print "another arg:", arg</p> <p>test_var_args(1, "two", 3)
执行结果:

formal arg: 1
another arg: two
another arg: 3

紧接着演示如何使用**kwargs参数传递keyworded形式的参数:

<br /> def test_var_kwargs(farg, **kwargs):<br /> print "formal arg:", farg<br /> for key in kwargs:<br /> print "another keyword arg: %s: %s" % (key, kwargs[key])</p> <p>test_var_kwargs(farg=1, myarg2="two", myarg3=3)
执行结果:

formal arg: 1
another keyword arg: myarg2: two
another keyword arg: myarg3: 3

关于这种变长参数列表的应用还有很多,但是这里了解这些就足够完成优先级划分的工作了。[1]

结论:从上面的原理和函数定义可以看到,如果按照第二种监听定义方式,则只需要在listenTo(xxx)的参数中加入priority=y即可。例如:
self.listenTo(core.openflow, priority=10)
最后再贴下注释内容:

priority : The order in which to call event handlers if there are multiple
for an event type. Should probably be an integer, where higher
means to call it earlier. Do not specify if you don’t care.

注:
[1] Python中如何使用*args 和 **kwargs, http://www.codecho.com/how-to-use-args-and-kwargs-in-python/