巨蟒函数指针

我有一个函数名存储在一个变量中,如下所示:

myvar = 'mypackage.mymodule.myfunction'

现在我要像这样调用我的函数

myvar(parameter1, parameter2)

达到这个目的最简单的方法是什么?

156358 次浏览

最简单

eval(myvar)(parameter1, parameter2)

你没有一个函数“指针”。你有一个函数“名称”。

虽然这样做效果很好,但是会有大量人员告诉您这是“不安全的”或“安全风险”。

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


funcdict[myvar](parameter1, parameter2)
def f(a,b):
return a+b


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

输出

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

为什么不存储函数本身? myvar = mypackage.mymodule.myfunction更干净。

只存储函数本身要好得多,因为它们是 python 中的第一类对象。

import mypackage


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

但是,如果必须动态地导入包,那么可以通过以下方式实现:

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


myfunction(parameter1, parameter2)

然而,请记住,所有这些工作都适用于您当前所处的任何范围。如果您不以某种方式持久化它们,那么如果您离开了本地范围,就不能指望它们继续存在。

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

编译(... ,‘ eval’)只允许一条语句,因此在调用之后不能有任意的命令,否则将出现 SyntaxError。然后一点点的验证至少可以限制表达在你的能力范围内,比如测试“ mypackage”的开始。

我在创建处理身份验证的库时遇到了类似的问题。我希望使用我的库的应用程序所有者能够向库注册一个回调,以便根据身份验证者所在的 LDAP 组检查授权。该配置作为一个 config.py 文件传入,该文件被导入,并包含一个包含所有配置参数的 dict。

我来搞定:

>>> 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!

有没有比喻的方法?