A function in Python is a first class object.  In the code below, f is defined 
inside of gen_datapath_join_callback, and you get a new f.  Since a function is 
just an object, gen_datapath_join_callback then adds a new property to f -- the 
cb property.  Inside f, this property is accessed.

I didn't write this piece of code, but it can actually be done a bit more 
simply.  I would write it like this:
def gen_datapath_join_callback(handler):
    def f(event):
        attrs = {}
        attrs[core.N_BUFFERS] = event.n_buffers
        attrs[core.N_TABLES] = event.n_tables
        attrs[core.CAPABILITES] = event.capabilities
        attrs[core.ACTIONS] = event.actions
        attrs[core.PORTS] = event.ports
        for i in range(0, len(attrs[core.PORTS])):
            port = attrs[core.PORTS][i]
            config = port['config']
            state = port['state']
            attrs[core.PORTS][i]['link']    = (state & 
openflow.OFPPS_LINK_DOWN) == 0
            attrs[core.PORTS][i]['enabled'] = (config & 
openflow.OFPPC_PORT_DOWN) == 0
            attrs[core.PORTS][i]['flood']   = (config & 
openflow.OFPPC_NO_FLOOD)  == 0

        ret = handler(event.datapath_id, attrs)
        if ret == None:
            return CONTINUE
        return ret
    return f

I don't know how much that explains.  The big point is that a function is an 
object  like any other: it has properties, it can be passed around and 
returned, and there can be multiple instances of it.

As for how f is invoked...

register_for_datapath_join() takes a callback function (handler) that is 
supposed to get called on datapath join.
Rather than actually have the given handler be the callback function, 
gen_datapath_join_callback() is used to generate a wrapper function.  The 
callback that gen_datapath_join_callback() creates (f) does some stuff (e.g., 
stocking the attrs dictionary), and then calls handler.
So the NOX event system calls f (via pyrt's Python_event_manager), and f calls 
the user-provided handler function.

I hope that sheds at least a little light.

-- Murphy

On Nov 2, 2011, at 7:03 AM, hzy wrote:

> Hi all:
> when I look at the code in nox/src/nox/lib/util.py written in python. I was 
> confused about some codes there. Because I am newbie to python.
> 
> def gen_datapath_join_callback(handler):
>     def f(event):
>         attrs = {}
>         attrs[core.N_BUFFERS] = event.n_buffers
>         attrs[core.N_TABLES] = event.n_tables
>         attrs[core.CAPABILITES] = event.capabilities
>         attrs[core.ACTIONS] = event.actions
>         attrs[core.PORTS] = event.ports
>         for i in range(0, len(attrs[core.PORTS])):
>             port = attrs[core.PORTS][i]
>             config = port['config']
>             state = port['state']
>             attrs[core.PORTS][i]['link']    = (state & 
> openflow.OFPPS_LINK_DOWN) == 0
>             attrs[core.PORTS][i]['enabled'] = (config & 
> openflow.OFPPC_PORT_DOWN) == 0
>             attrs[core.PORTS][i]['flood']   = (config & 
> openflow.OFPPC_NO_FLOOD)  == 0
> 
>         ret = f.cb(event.datapath_id, attrs)
>         if ret == None:
>             return CONTINUE
>         return ret
>     f.cb = handler
>     return f
>  
> Python can define a function in a function really confused me. I do not know 
> how the function f(event) is invoked. and what the f.cb mean.
> Any ideas?
> Thanks forward.
> hzy
> _______________________________________________
> nox-dev mailing list
> nox-dev@noxrepo.org
> http://noxrepo.org/mailman/listinfo/nox-dev

_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev

Reply via email to