How to use a variable as function name in Python

The trick is to use globals():

globals()['use_variable_as_function_name']()

will be equivalent to

use_variable_as_function_name()

found at: George Sakkis https://bytes.com/topic/python/answers/792283-calling-variable-function-name


The following is a useful application of the above questioning I needed right now (that's why I came here): apply special functions to URLs depending on their nature:

l = ['condition1', 'condition2', 'condition3']

I used to write

if 'condition1.' in href:
    return do_something_condition1()
if 'condition2.' in href:
    return do_something_condition2()
if 'condition3.' in href:
    return do_something_condition3()

and so on - my list has 19 members by now and keeps growing.

While investigating the subject and developing, the function code had been quite naturally part of the main function making it soon horrible to read, so relocating the working code into functions was a great relief already.

This clumsy code above can be substituted by:

for e in l:              # this is my condition list
    if e + '.' in href:  # this is the mechanism to choose the right function
        return globals()['do_something_' + e]()

This way the main code stays simple and legible no matter how long the list of conditions may grow.

Those functions corresponding to the condition labels have to be declared conventionally, of course, depending on the nature of the type of the URL in question:

def do_something_condition1(href):
    # special code 1
    print('========1=======' + href)

def do_something_condition2(href):
    # special code 2
    print('========2=======' + href)

def do_something_condition3(href):
    # special code 3
    print('========3=======' + href)

Test:

>>> href = 'https://google.com'
>>> for e in l:
...     globals()['do_something_' + e](href)
...
========1=======https://google.com
========2=======https://google.com
========3=======https://google.com

Or, to model it closer to the above scenario:

success = '________processed successfully___________ ' 

def do_something_google(href):
    # special code 1
    print('========we do google-specific stuff=======')
    return success + href 

def do_something_bing(href):
    # special code 2
    print('========we do bing-specific stuff=======')
    return success + href 

def do_something_wikipedia(href):
    # special code 3
    print('========we do wikipedia-specific stuff=======')
    return success + href 

Test:

l = ['google', 'bing', 'wikipedia']

href = 'https://google.com'

def test(href):
    for e in l:
        if e + '.' in href:
            return globals()['do_something_' + e](href)

>>> test(href)
========we do google-specific stuff=======
'________processed successfully___________ https://google.com'

Result:

Further elaboration on the problem now just amounts to augment the condition list one by one and write the corresponding functions depending on the argument. The above mechanism will pick the right one thereafter.


You can't define a function using a variable but you can rebind the function to the variable name. Here is an example to add them to the module's global namespace.

one = 'one'
two = 'two'
three = 'three'
l = [one, two, three]
def some_stuff():
    print("i am sure some stuff")
for item in l:
    def _f():
        some_stuff()
    globals()[item] = _f
    del _f

one()
two()
three()

Functions in Python are objects that have a name referencing them, so you can pass them around, store in lists and dictionaries (common use when creating jump-tables).

I.e. this works:

   def one():
        print "1"

    def two():
        print "2"

    def three():
        print "3"

    l = [one, two, three]

    for item in l:
        item()

Will print:

1
2
3

Don't use list as variable name, because this way you redefine buildin.

def is the statement that is also executed, unlike function defenitions in compiled languages. So when you call def item(): you don't define function for one, two, three, but redefine item name.

In general it is not quite clear what you're trying to do, but it doesn't look like a good idea. May be explain what you try to accomplish, or rethink the way you want to do it.


Here is a workaround wrapped in a class. It uses a dictionary for the mapping:

class function_class:
    def __init__(self,fCase):
        fDic = {'A':self.A,         # mapping: string --> variable = function name
                'B':self.B,
                'C':self.C}
        self.fActive = fDic[fCase]
    def A(self): print('here runs function A')
    def B(self): print('here runs function B')
    def C(self): print('here runs function C')
    def run_function(self):
        self.fActive()

#---- main ----------        
fList = ['A','B','C']              # list with the function names as strings
for f in fList:                    # run through the list
    g = function_class(f)
    g.run_function()

The output is:

here runs function A
here runs function B
here runs function C