Список Python как * аргументы? - PullRequest
3 голосов
/ 06 апреля 2010

У меня есть две функции Python, каждая из которых принимает переменные аргументы в своих определениях функций. Чтобы привести простой пример:

def func1(*args):
    for arg in args:
        print arg

def func2(*args):
    return [2 * arg for arg in args]

Я хотел бы составить их - как в func1(func2(3, 4, 5)) - но я не хочу, чтобы args в func1 было ([6, 7, 8],), я хочу, чтобы оно было (6, 7, 8), как если бы оно назывался func1(6, 7, 8), а не func1([6, 7, 8]).

Обычно я просто использовал бы func1(*func2(3, 4, 5)) или имел бы func1 проверку, чтобы увидеть, был ли args[0] списком. К сожалению, я не могу использовать первое решение в данном конкретном случае, и для применения второго потребуется такая проверка во многих местах (в роли func1 имеется множество функций.

).

У кого-нибудь есть идеи, как это сделать? Я полагаю, что можно использовать какую-то интроспекцию, но я могу ошибаться.

Ответы [ 3 ]

4 голосов
/ 06 апреля 2010

Можно рассмотреть написание функции декоратора, который проверяет, является ли первый аргумент списком. Применение декоратора к существующим функциям немного проще, чем изменение функций.

3 голосов
/ 06 апреля 2010

Вы можете использовать Декоратор, опубликованный Ярославом.

Минимальный пример:

def unpack_args(func):
    def deco_func(*args):
        if isinstance(args, tuple):
            args = args[0]

        return func(*args)

    return deco_func


def func1(*args):
    return args

def func2(*args):
    return args

@unpack_args
def func3(*args):
    return args

print func1(1,2,3)    # > (1,2,3)
print func2(1,2,3)    # > (1,2,3)
print func1(*func2(1,2,3))    # > (1,2,3)
print func1(func2(1,2,3))    # > ( (1,2,3), )
print func3(func2(1,2,3))   # > (1,2,3)
1 голос
/ 06 апреля 2010

Обычно, я бы просто использовал func1(*func2(3, 4, 5)) или проверил func1, чтобы посмотреть, было ли args[0] list. К сожалению, я не могу использовать первое решение в данном конкретном случае, и для применения второго потребуется такая проверка во многих местах (в роли func1 много функций).

Почему вы не можете использовать первое решение?

>>> def func1(*args):
    for arg in args:
        print arg

>>> def func2(*args):
    return [2 * arg for arg in args]

>>> func2(3, 4, 5)
[6, 8, 10]
>>> func1(1,2,3)
1
2
3
>>> func1(*func2(3, 4, 5))
6
8
10
>>> 

Если это было невозможно, вы все равно могли бы использовать func1(*tuple(func2(3, 4, 5))) (но вам это не нужно).

...