开发者

Python function pointer

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

myvar = 'mypackage.mymodule.myf开发者_JS百科unction'

and I now want to call myfunction like this

myvar(parameter1, parameter2)

What's the easiest way to achieve this?


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

funcdict[myvar](parameter1, parameter2)


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.


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

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

OUTPUT

 5


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".


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


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


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.


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜