RadiantHex
RadiantHex

Reputation: 25597

Dynamically calling functions - Python

I have a list of functions... e.g.

def filter_bunnies(pets): ...

def filter_turtles(pets): ...

def filter_narwhals(pets): ...

Is there a way to call these functions by using a string representing their name?

e.g.

'filter_bunnies', 'filter_turtles', 'filter_narwhals'

Upvotes: 6

Views: 3560

Answers (8)

Dan Menes
Dan Menes

Reputation: 6797

Usually, when I need to dispatch a function call to one of several functions based on a string, I will make the functions elements of a dict. I've done this, for example, in writing a simple interpreter, where each keyword is implemented by a different function. You can even use decorators to elegantly take care of the assignments:

KEYWORD_FUNCTIONS = {}

def MAKE_KEYWORD( f ):
    KEYWORD_FUNCTIONS[ f.func_name ] = f
    return f

@MAKE_KEYWORD
def KEYWORD_A( arg ):
    print "Keyword A with arg %s" % arg

@MAKE_KEYWORD
def KEYWORD_B( arg ):
    print "Keyword B with arg %s" % arg

if __name__ == "__main__":
    KEYWORD_FUNCTIONS[ "KEYWORD_A" ]( "first_argument" )
    KEYWORD_FUNCTIONS[ "KEYWORD_B" ]( "second_argument" )

Upvotes: 0

PaulMcG
PaulMcG

Reputation: 63782

My code crystal ball detects that there may be some commonality among your filter functions. Are they really different functions, or are they all the same with just a single filter value that is different? If you have substantial repetition in a program, stop and think if it is worth some refactoring into a single common function, which will be much more maintainable than a set of very similar functions. You could have a single function filterByType that takes 2 arguments, the list of pets and the filtering type, and then just define a dict to map input strings to the type object or class that you mean to filter by.

Upvotes: 2

Ivan
Ivan

Reputation: 1796

The easiest and ugliest way would be to call it by using eval function, which would evaluate your string. Much cleaner solution is to use getattr function on a module to which function belongs to obtain function's reference, and then call it by reference.

Another way that just occurred to me to obtain function-s reference would be with use of eval function like this func = eval("filter_bunnies")

Be careful when you're using eval, especially if the value of eval is dependent on some sort of user input as it could make you execute unwanted/malicious code.

Upvotes: 0

Jakub Hampl
Jakub Hampl

Reputation: 40573

See the eval function.

Upvotes: 0

Olivier Verdier
Olivier Verdier

Reputation: 49246

Yes, you can use:

globals()['filter_bunnies']()

to call 'filter_bunnies'.

Upvotes: 4

ZelluX
ZelluX

Reputation: 72775

You can use the built-in function locals() to get a dictionary of variables and functions, here is an example:

def a(str):
    print("A" + str)

def b(str):
    print("B" + str)

def c(str):
    print("C" + str)

for f in ['a', 'b', 'c']:
    locals()[f]('hello')

Upvotes: 2

SilentGhost
SilentGhost

Reputation: 320009

Are your function a part of an object? If so you could use getattr function:

>> class A:
    def filter_bunnies(self, pets):
        print('bunnies')

>>> getattr(A(), 'filter_bunnies')(1)
bunnies

Upvotes: 11

user180100
user180100

Reputation:

using eval?

Upvotes: 0

Related Questions