[英]Python: Passing a function name as an argument in a function
我试图将一个函数的名称作为参数传递给另一个函数,但出现错误:“类型错误:‘str’对象不可调用”。 这是问题的一个简化示例:
def doIt(a, func, y, z):
result = z
result = func(a, y, result)
return result
def dork1(arg1, arg2, arg3):
thing = (arg1 + arg2) / arg3
return thing
def dork2(arg1, arg2, arg3):
thing = arg1 + (arg2 / arg3)
return thing
当我像这样调用 doIt 时:
var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)
我得到:
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
ned = doIt(3, var, 4, 9)
File "<pyshell#2>", line 3, in doIt
result = func(a, y, result)
TypeError: 'str' object is not callable
如果你想传递函数的name ,正如你所说的和你正在做的,当然你不能调用它——为什么要“调用一个名字”? 毫无意义。
如果要调用它,传递函数本身,即最强调不
var = 'dork1'
反而
var = dork1
没有引号!
编辑:OP 在评论(!)中想知道如何在给定函数名称(作为字符串)的情况下获取函数对象。 碰巧我刚刚在我在 OSCON 教过的教程中展示了如何做到这一点(我刚回来)——从这里获取幻灯片并查看第 47 页,“延迟加载回调”:
class LazyCallable(object):
def __init__(self, name):
self.n, self.f = name, None
def __call__(self, *a, **k):
if self.f is None:
modn, funcn = self.n.rsplit('.', 1)
if modn not in sys.modules:
__import__(modn)
self.f = getattr(sys.modules[modn],
funcn)
self.f(*a, **k)
所以你可以通过LazyCallable('somemodule.dork1')
并LazyCallable('somemodule.dork1')
过上幸福的生活。 如果您当然不需要处理模块(这一定意味着多么奇怪的架构!-),调整此代码很容易。
我很高兴找到这个,我不知道这是否得到了回答。 我对此的解决方案如下:
def doIt(func, *args):
func_dict = {'dork1':dork1,'dork2':dork2}
result = func_dict.get(func)(*args)
return result
def dork1(var1, var2, var3):
thing = (float(var1 + var2) / var3)
return thing
def dork2(var1, var2, var3):
thing = float(var1) + (float(var2) / var3)
return thing
这可以按如下方式运行:
func = 'dork2'
ned = doIt(func,3, 4, 9)
print ned
不要传递函数的名称。
传递函数。
fun = dork1
ned = doIt(3, fun, 4, 9)
print (ned)
var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)
在这个例子中, var
是一个字符串。 doIt
函数“调用”它的第二个参数(为此传递var
)。 改为传递一个函数。
您可能不应该这样做,但您可以使用 eval() 获取该函数
例如,要使用 len,
eval("len")(["list that len is called on"])
def run_function(function_name):
function_name()
在这个例子中,调用run_function(any_function)
将调用any_function()
。
函数是python中的一等对象。 做这个:
var = dork1
如果必须传递字符串,例如用户输入,则:
globals()[var]
将查找函数对象。
class renderAttributes():
def __init__(self, name):
self.name = name
def decorator_function(self, func_name):
func_dict = {'my_function': self.my_function}
def wrapper_function():
result = func_dict.get(func_name)()
return result
return wrapper_function
def my_function(self):
//Do whatever you want to do
return self.name
然后我可以创建一个 renderAttributes 类的对象,并通过简单地传递函数名称来调用类中定义的任何方法,如下所示
render_attr_obj = renderAttributes('Bob')
return_function = render_attr_obj.decorator_function('my_function')
return_functon()
return_function = renderAttributes('Rob')
return_function = render_attr_obj.decorator_function('my_function')
return_functon()
如果这些函数是类的一部分,则getattr可能会起作用。
class SomeClass():
def doIt(self, a, func, y, z):
result = z
result = getattr(self, func)(a, y, result)
return result
def dork1(self, arg1, arg2, arg3):
thing = (arg1 + arg2) / arg3
return thing
def dork2(self, arg1, arg2, arg3):
thing = arg1 + (arg2 / arg3)
return thing
尝试从sys.argv
传递函数名称时,它对我有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.