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
Когда я вызываю 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
Ответы
Ответ 1
Если вы хотите передать функцию имя, как вы сказали, и вы это делаете, конечно, вы не можете ее назвать - зачем "называть имя"? Это бессмысленно.
Если вы хотите вызвать его, пропустите функцию, то есть наиболее решительно не
var = 'dork1'
а скорее
var = dork1
без кавычек!
Изменить: ОП задается вопросом (!) как получить объект функции с именем функции (в виде строки). Как бы то ни было, я просто показал, как это сделать в учебнике, которое я преподавал в OSCON (из которого я только что вернулся) - получить слайды из здесь и см. стр. 47, "Lazy-load callbacks":
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')
и жить долго и счастливо. Если вам не нужно иметь дело с модулем, конечно (какая странная архитектура должна подразумевать!), Легко настроить этот код.
Ответ 2
Не передавать имя функции.
Передайте функцию.
fun = dork1
ned = doIt(3, fun, 4, 9)
print (ned)
Ответ 3
var = 'dork1'
ned = doIt(3, var, 4, 9)
print (ned)
В этом примере var
- это строка. Функция doIt
"вызывает" свой второй аргумент (для которого вы проходите var
). Передайте вместо этого функцию.
Ответ 4
Вероятно, вы не должны этого делать, но вы можете получить функцию, используя eval()
например, для использования len,
eval("len")(["list that len is called on"])
Ответ 5
Я был взволнован, чтобы найти это, и я не знаю, ответили ли на это. Мое решение заключается в следующем:
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
Ответ 6
Функции являются первоклассными объектами в python. Сделайте это:
var = dork1
Если вы должны передать строку, например, ввод пользователя, то:
globals()[var]
будет искать объект функции.
Ответ 7
def run_function(function_name):
function_name()
В этом примере вызов run_function(any_function)
вызовет any_function()
.