Question

I'm using the dispatch pattern in python like this....

    ok = parse_qsl(urlparse(u).query, keep_blank_values=True)

    eventType = (ok[9][1])
    nName = (ok[10][1])
    hName = (ok[11][1])
    cName = (ok[12][1])

    def newChannel(cName):
        queue = j.queue(cName)
        r = queue.add_subscribers(*[subscriberCreateChanTable, subscriberSortScenes])

    def newNetwork(hName):
        queue = j.queue(hName)
        r = queue.add_subscribers(*[subscriber1a])

    def loginError(nName):
        pass

    action = {'newChannel': newChannel,
             'newNetwork': newNetwork , 'loginError': loginError}

    handler = action.get(eventType)
    handler(cname)

How do I pass different function parameters to the mapped function so if eventType = "newChannel", then newChannel function will get called with cname, but if eventType = "newNetwork", how do i call it with hname variable instead.

just call handler(hname)?

    handler(hname)
    handler(cname)
    handler(nName)

?

Was it helpful?

Solution

You can either use a lambda or partial or just store the params in the dict too:

action = {'newChannel': (newChannel, hname),
             'newNetwork': (newNetwork, cname) , 'loginError': (loginError, nName)}

handler, param = action.get(eventType)
handler(param)

Now it still means you have to build action on each request. Another solution that avoids this is to write "getter" for the params and store (handler, getter) pairs:

def newChannel(cName):
    queue = j.queue(cName)
    r = queue.add_subscribers(*[subscriberCreateChanTable, subscriberSortScenes])

def newNetwork(hName):
    queue = j.queue(hName)
    r = queue.add_subscribers(*[subscriber1a])

def loginError(nName):
    pass

def hName(ok):
    return ok[11][1]

def cName(ok):
    return ok[12][1]

def nName(ok):
    return ok[10][1]

def eventType(ok):
    return ok[9][1]


action = {
    'newChannel': (newChannel, cName),
    'newNetwork': (newNetwork, hName),
    'loginError': (loginError, nName)
     }


ok = parse_qsl(urlparse(u).query, keep_blank_values=True)
handler, getter = action.get(eventType(ok))
handler(getter(ok))

The same example using lambdas:

action = {
    'newChannel': lambda ok: newChannel(cName(ok)),
    'newNetwork': lambda ok: newNetwork(hName(ok)),
    'loginError': lambda ok: loginError(nName(ok))
     }

ok = parse_qsl(urlparse(u).query, keep_blank_values=True)

handler = action.get(eventType(ok))
handler(ok)

In this case it just makes for less explicit code and useless overhead IMHO, but sometimes a lambda-based solution let you capture some additional context that's not available at the point you define your other functions.

Or you could have done the param parsing in the lambdas themselves, ie :

action = {
    'newChannel': lambda ok: newChannel(ok[12][1]),
    'newNetwork': lambda ok: newNetwork(ok[11][1]),
    'loginError': lambda ok: loginError(ok[10][1])
     }

but that's still less explicit (and less testable) than using plain functions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top