Python:将函数名称作为函数中的参数传递

时间:2010-07-28 00:56:19

标签: python

我试图将函数的名称作为参数传递给另一个函数,但是我得到一个错误:“TypeError:'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

我打电话的时候是这样的:

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

9 个答案:

答案 0 :(得分:27)

如果您想传递函数的名称,正如您所说的那样,当然您无法调用它 - 为什么会“调用名称“?这毫无意义。

如果您想调用它,请传递函数本身,也就是说,最强调

var = 'dork1'

而是

var = dork1

没有引号!

编辑:OP在评论(!)中想知道如何在给定函数名称(作为字符串)的情况下获取函数对象。碰巧我只是在我在OSCON上教过的教程中展示了如何做到这一点(从中我刚刚回来) - 从here获取幻灯片并参见第47页“延迟加载回调”:< / p>

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')并过上幸福的生活。如果您当然不需要处理模块(这是一个必须暗示的奇怪架构! - ),则可以轻松调整此代码。

答案 1 :(得分:4)

不要传递函数的名称。

传递功能。

fun = dork1
ned = doIt(3, fun, 4, 9)
print (ned)

答案 2 :(得分:3)

我很高兴能找到这个并且我不知道这是否得到了回答。我对此的解决方案如下:

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

答案 3 :(得分:2)

var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)

在此示例中,var是一个字符串。 doIt函数“调用”它的第二个参数(为其传递var)。传递一个函数。

答案 4 :(得分:1)

您可能不应该这样做,但您可以使用eval()

来获取该功能

例如,使用len,

eval("len")(["list that len is called on"])

答案 5 :(得分:0)

函数是python中的第一类对象。这样做:

var = dork1

如果必须传递字符串,例如用户输入,则:

globals()[var]

将查找函数对象。

答案 6 :(得分:0)

def run_function(function_name):
    function_name()

在此示例中,调用run_function(any_function)将调用any_function()

答案 7 :(得分:0)

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() 

答案 8 :(得分:0)

如果这些函数是类的一部分,则

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传递函数名称时,它对我有用。