Расширение кортежей в аргументах
Есть ли способ развернуть кортеж Python в функцию - как фактические параметры?
Например, здесь expand()
делает магию:
tuple = (1, "foo", "bar")
def myfun(number, str1, str2):
return (number * 2, str1 + str2, str2 + str1)
myfun(expand(tuple)) # (2, "foobar", "barfoo")
Я знаю, что можно определить myfun
как myfun((a, b, c))
, но, конечно, может существовать устаревший код.
Благодаря
Ответы
Ответ 1
myfun(*tuple)
делает именно то , что вы запрашиваете.
Побочная проблема: не используйте в качестве идентификаторов встроенные имена типов, такие как tuple
, list
, file
, set
и т.д. - это ужасная практика, и она вернется и укусит вас, когда вы меньше всего этого ожидаете, поэтому просто зайдите в привычка активно избегать сокрытия встроенных имен с вашими собственными идентификаторами.
Ответ 2
Обратите внимание, что вы также можете развернуть часть списка аргументов:
myfun(1, *("foo", "bar"))
Ответ 3
Посмотрите учебник Python, раздел 4.7.3 и 4.7.4.
Он говорит о передаче кортежей в качестве аргументов.
Я также хотел бы использовать именованные параметры (и передавать словарь) вместо использования кортежа и передачи последовательности. Я считаю, что использование позиционных аргументов является плохой практикой, когда позиции не интуитивно понятны или не существует нескольких параметров.
Ответ 4
Это метод функционального программирования. Он поднимает функцию расширения кортежа из синтаксического сахара:
apply_tuple = lambda f, t: f(*t)
Пример использования:
from toolz import *
from operator import add, eq
apply_tuple = curry(apply_tuple)
thread_last(
[(1,2), (3,4)],
(map, apply_tuple(add)),
list,
(eq, [3, 7])
)
# Prints 'True'
apply_tuple
карри для apply_tuple
экономит много partial
вызовов в долгосрочной перспективе.
Ответ 5
Я столкнулся с подобной проблемой и создал эту функцию, которая расширяет фиксированную функцию. Надеюсь это поможет.
def run_argtup(func, argvalues):
"""
Execute any functions with their arguments in tuple.
:param func:
:param argvalues:
:return:
"""
argnames = get_func_argnames(func)
if len(argnames) != len(argvalues):
raise ValueError("Length of args doens't match.")
for argn, argv in zip(argnames, argvalues):
exec('{}=argv'.format(argn))
return eval('func(%s, %s)' % argnames)