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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3349157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:36:15  来源:igfitidea点击:

Python: Passing a function name as an argument in a function

python

提问by Desmond

I am trying to pass the name of a function into another function as an argument but I get an error: "TypeError: 'str' object is not callable". Here is a simplified example of the problem:

我试图将一个函数的名称作为参数传递给另一个函数,但出现错误:“类型错误:‘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

When I call doIt like so:

当我像这样调用 doIt 时:

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

I get:

我得到:

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

回答by Alex Martelli

If you want to pass the function's name, as you said and you're doing, of course you can't call it -- why would one "call a name"? It's meaningless.

如果你想传递函数的name,正如你所说的和你正在做的,当然你不能调用它——为什么要“调用一个名字”?毫无意义。

If you want to call it, pass the function itself, that is, most emphatically not

如果要调用它,传递函数本身,即最强调

var = 'dork1'

but rather

反而

var = dork1

without quotes!

没有引号!

Edit: the OP wonders in a comment (!) how to get a function object given the function name (as a string). As it happens I just showed how to do that in a tutorial I taught at OSCON (from which I'm just back) -- get the slides from hereand see page 47, "Lazy-loading callbacks":

编辑: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)

So you could pass LazyCallable('somemodule.dork1')and live happily ever after. If you don't need to deal with the module of course (what a weird architecture that must imply!-) it's easy to adjust this code.

这样你就可以过去了LazyCallable('somemodule.dork1'),从此过上幸福的生活。如果您当然不需要处理模块(这一定意味着多么奇怪的架构!-),调整此代码很容易。

回答by S.Lott

Don't pass the name of a function.

不要传递函数的名称。

Pass the function.

传递函数。

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

回答by advait

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

In this example, varis a string. The doItfunction "calls" its second argument (for which you pass var). Pass a function instead.

在这个例子中,var是一个字符串。该doIt函数“调用”它的第二个参数(您传递的参数var)。改为传递一个函数。

回答by Mark Tolonen

Functions are first-class objects in python. Do this:

函数是python中的一等对象。做这个:

var = dork1

If you must pass a string, such as user input, then:

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

globals()[var]

will look up the function object.

将查找函数对象。

回答by Bwmat

You probably shouldn't do this, but you can get the function using eval()

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

for example, to use len,

例如,要使用 len,

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

回答by user2757128

I was thrilled to find this and I don't know if this was answered. My solution to this is as follows:

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

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

This can be run as follows:

这可以按如下方式运行:

func = 'dork2'
ned = doIt(func,3, 4, 9)
print ned

回答by Zenadix

def run_function(function_name):
    function_name()

In this example, calling run_function(any_function)will call any_function().

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