Python – список кортежей функций / аргументов

def f1(n): #accepts one argument pass def f2(): #accepts no arguments pass FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments (f1,(6)), (f2,())] for f, arg in FUNCTION_LIST: f(arg) 

Третий раз в цикле он пытается передать пустой набор аргументов функции, которая не принимает аргументов. Он дает ошибку TypeError: f2() takes no arguments (1 given) . Первые два вызова функции работают правильно – содержимое кортежа передается, а не сам кортеж.

Избавление от пустого кортежа аргументов в записи оскорбительного списка не решает проблему:

 FUNCTION_LIST[2] = (f2,) for f,arg in FUNCTION_LIST: f(arg) 

приводит к ValueError: need more than 1 value to unpack .

Я также пробовал перебирать индекс, а не элементы списка.

 for n in range(len(FUNCTION_LIST)): FUNCTION_LIST[n][0](FUNCTION_LIST[n][1]) 

Это дает тот же TypeError в первом случае, и IndexError: tuple index out of range когда третий элемент списка (f2,) .

Наконец, нотация звездочки не работает. На этот раз это ошибки при вызове f1 :

 for f,args in FUNCTION_LIST: f(*args) 

дает TypeError: f1() argument after * must be a sequence, not int .

У меня не хватило сил, чтобы попробовать. Я все еще думаю, что первый должен работать. Может кто-то указать мне верное направление?

4 Solutions collect form web for “Python – список кортежей функций / аргументов”

Ваш комментарий в этом фрагменте кода показывает неправильное представление в этом контексте:

 FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments (f1,(6)), (f2,())] 

Выражения (2) и (6) не являются кортежами – они являются целыми числами. Вы должны использовать (2,) и (6,) для обозначения одноэлементных кортежей, которые вы хотите. После исправления этого кода цикла должен выглядеть так:

 for f, args in FUNCTION_LIST: f(*args) 

См. Раздел Распаковка списков аргументов в учебнике Python для объяснения синтаксиса *args .

Проблема в том, что такие обозначения:

 (6) 

оценивает целочисленное значение и вам нужен кортеж, поэтому напишите так:

 (6, ) 

и ваша звездочка будет успешной.

Попробуйте передать *() вместо () . Символ * сообщает python, чтобы распаковать итерабель, который следует за ним, поэтому он распаковывает пустой кортеж и ничего не передает функции, поскольку кортеж пуст.

Для записи хорошая альтернатива, с которой я обнаружил, – это использование functools.partial . Следующий код делает то, что я пытаюсь сделать:

 from functools import partial def f1(n): #accepts one argument pass def f2(): #accepts no arguments pass FUNCTION_LIST = [partial(f1,2), #each list entry is a callable with the argument pre-ordained partial(f1,6), partial(f2)] #the call to partial is not really necessary for the entry with no arguments. for f in FUNCTION_LIST: f() 
  • Создание и работа со списком списков списков: в Python
  • Python проверяет, находятся ли элементы в списке
  • Какой конец списка является вершиной?
  • Сравнение списков словарей
  • Убедитесь, что все значения в списке больше определенного номера
  • Ссылка на элемент в списке кортежей
  • Список папок в Python
  • python: как сортировать списки по алфавиту по заглавным буквам
  • Python - лучший язык программирования в мире.