drjeep
drjeep

Reputation: 1039

Python dynamic function names

I'm looking for a better way to call functions based on a variable in Python vs using if/else statements like below. Each status code has a corresponding function

if status == 'CONNECT':
    return connect(*args, **kwargs)
elif status == 'RAWFEED':
    return rawfeed(*args, **kwargs)
elif status == 'RAWCONFIG':
    return rawconfig(*args, **kwargs)
elif status == 'TESTFEED':
    return testfeed(*args, **kwargs)
...

I assume this will require some sort of factory function but unsure as to the syntax

Upvotes: 11

Views: 20478

Answers (8)

hasen
hasen

Reputation: 166122

Look at this: getattra as a function dispatcher

Upvotes: 3

Eugene Morozov
Eugene Morozov

Reputation: 15806

Some improvement to SilentGhost's answer:

globals()[status.lower()](*args, **kwargs)

if you want to call the function defined in the current module.

Though it looks ugly. I'd use the solution with dictionary.

Upvotes: 4

RailsSon
RailsSon

Reputation: 20637

I encountered the same problem previously. Have a look at this question, I think its what you are looking for.

Dictionary or If Statements

Hope this is helpful

Eef

Upvotes: 1

to-chomik
to-chomik

Reputation: 371

it seams that you can use getattr in a slightly different (in my opinion more elegant way)

import math
getattr(math, 'sin')(1)

or if function is imported like below

from math import sin

sin is now in namespace so you can call it by

vars()['sin'](1)

Upvotes: 6

linjunhalida
linjunhalida

Reputation: 4655

some change from previous one:

funcs = {
'CONNECT': connect,
'RAWFEED': rawfeed,
'RAWCONFIG' : rawconfig,
'TESTFEED': testfeed
}

func = funcs.get('status')
if func:
    func(*args, **kwargs)

Upvotes: 0

SilentGhost
SilentGhost

Reputation: 319561

you might find getattr useful, I guess

import module
getattr(module, status.lower())(*args, **kwargs)

Upvotes: 38

unbeknown
unbeknown

Reputation:

The canonical way to do this is to use a dictionary to emulate switch or if/elif. You will find several questions to similar problems here on SO.

Put your functions into a dictionary with your status codes as keys:

funcs = {
    'CONNECT': connect,
    'RAWFEED': rawfeed,
    'RAWCONFIG' : rawconfig,
    'TESTFEED': testfeed
}
funcs[status](*args, **kwargs)

Upvotes: 20

vartec
vartec

Reputation: 134581

assuming that these functions belong to some module:

import module
return getattr(module, status.lower()).__call__(*args, **kwargs)

Upvotes: 15

Related Questions