Python function pointer

PythonFunction Pointers

Python Problem Overview


I have a function name stored in a variable like this:

myvar = 'mypackage.mymodule.myfunction'

and I now want to call myfunction like this

myvar(parameter1, parameter2)

What's the easiest way to achieve this?

Python Solutions


Solution 1 - Python

funcdict = {
  'mypackage.mymodule.myfunction': mypackage.mymodule.myfunction,
    ....
}

funcdict[myvar](parameter1, parameter2)

Solution 2 - Python

It's much nicer to be able to just store the function itself, since they're first-class objects in python.

import mypackage

myfunc = mypackage.mymodule.myfunction
myfunc(parameter1, parameter2)

But, if you have to import the package dynamically, then you can achieve this through:

mypackage = __import__('mypackage')
mymodule = getattr(mypackage, 'mymodule')
myfunction = getattr(mymodule, 'myfunction')

myfunction(parameter1, parameter2)

Bear in mind however, that all of that work applies to whatever scope you're currently in. If you don't persist them somehow, you can't count on them staying around if you leave the local scope.

Solution 3 - Python

def f(a,b):
    return a+b

xx = 'f'
print eval('%s(%s,%s)'%(xx,2,3))

OUTPUT

 5

Solution 4 - Python

Easiest

eval(myvar)(parameter1, parameter2)

You don't have a function "pointer". You have a function "name".

While this works well, you will have a large number of folks telling you it's "insecure" or a "security risk".

Solution 5 - Python

Why not store the function itself? myvar = mypackage.mymodule.myfunction is much cleaner.

Solution 6 - Python

modname, funcname = myvar.rsplit('.', 1)
getattr(sys.modules[modname], funcname)(parameter1, parameter2)

Solution 7 - Python

eval(compile(myvar,'<str>','eval'))(myargs)

compile(...,'eval') allows only a single statement, so that there can't be arbitrary commands after a call, or there will be a SyntaxError. Then a tiny bit of validation can at least constrain the expression to something in your power, like testing for 'mypackage' to start.

Solution 8 - Python

I ran into a similar problem while creating a library to handle authentication. I want the app owner using my library to be able to register a callback with the library for checking authorization against LDAP groups the authenticated person is in. The configuration is getting passed in as a config.py file that gets imported and contains a dict with all the config parameters.

I got this to work:

>>> class MyClass(object):
...     def target_func(self):
...         print "made it!"
...    
...     def __init__(self,config):
...         self.config = config
...         self.config['funcname'] = getattr(self,self.config['funcname'])
...         self.config['funcname']()
... 
>>> instance = MyClass({'funcname':'target_func'})
made it!

Is there a pythonic-er way to do this?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionschneckView Question on Stackoverflow
Solution 1 - PythonIgnacio Vazquez-AbramsView Answer on Stackoverflow
Solution 2 - Pythonuser609095View Answer on Stackoverflow
Solution 3 - PythonPratik DeoghareView Answer on Stackoverflow
Solution 4 - PythonS.LottView Answer on Stackoverflow
Solution 5 - PythonironfroggyView Answer on Stackoverflow
Solution 6 - PythonMatt AndersonView Answer on Stackoverflow
Solution 7 - PythonSilverbackNetView Answer on Stackoverflow
Solution 8 - PythonRob FagenView Answer on Stackoverflow