1

I want to call that function by extracting the first word from the string. For example my string is like:

"my_func arg_1 arg_2"
#  ^       ^     ^ second argument of function
#  ^       ^ first argument of function 
#  ^ name of the function

where my_func is a name of the function already defined.

Based on the above mention string, I want to dynamically execute the my_func function. So, my function call should be like:

my_func(arg_1, arg_2)

Currently I am trying to achieve this via using eval:

eval(command.split(' ', 1)[0])

How can I achieve this?

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
zegulas
  • 417
  • 2
  • 6
  • 18

4 Answers4

2

You may use locals() (or globals()) to fetch the reference of function based on string. Below is the sample example:

# Sample function
def foo(a, b):
    print('{} - {}'.format(a, b))

# Your string with functions name and attributes
my_str = "foo x y"

func, *params = my_str.split()
# ^      ^ tuple of params string
# ^ function name string

Now, pass the function string as a key to the locals() dict with *params as argument to the function as:

>>> locals()[func](*params)
x - y   # output printed by `foo` function
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • What if the function is defined under an object? Can we do something like: `my_object.locals()[func]`? – alper Aug 08 '21 at 16:09
0

Regarding the split method, by default the delimiter is space so you don't actually need to define that your delimiter is space and as you want the first item in the list, you just need to type the index 0 [0].

locals returns a dictionary with a current local symbol table. globals returns a dictionary with global symbol table.

var = "my_func arg_1 arg_2"
print (locals()[var.split()[0]]())

Or

var = "my_func arg_1 arg_2"
print (globals()[var.split()[0]]())

If the function was part of an object you could use the getattr built-in function.

var = "my_func arg_1 arg_2"
getattr(object, var.split()[0])

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

omri_saadon
  • 10,193
  • 7
  • 33
  • 58
0

Something along the lines of: Check if the function exists inside the local scope.

If it does exist then run it using eval().

def add():
    print("do something")

def find_function(funct_name, defined_names):
    if defined_names.get(funct_name) is None:
        print("no function called {}".format(funct_name))
        return

    eval(funct_name + "()")

# access local user defined names.
defined_names = locals()
#print(defined_names)

function_name = 'add'
find_function(function_name ,defined_names)

Output:

do something

SkinnyTok
  • 23
  • 1
  • 6
0

If you define you functions up front you can have greater control over their name mapping.

def my_func(a):
    print(a)


functions = {'my_func': my_func}


def exe(text):
    command = text.split(" ")
    f = command[0]
    args = command[1:]
    if f in functions:
        functions[f](args)


exe("my_func arg_1 arg_2")
Nic
  • 253
  • 1
  • 3
  • 9