简体   繁体   中英

Python list as *args?

I have two Python functions, both of which take variable arguments in their function definitions. To give a simple example:

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

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

I'd like to compose them -- as in func1(func2(3, 4, 5)) -- but I don't want args in func1 to be ([6, 7, 8],) , I want it to be (6, 7, 8) , as if it was called as func1(6, 7, 8) rather than func1([6, 7, 8]) .

Normally, I would just use func1(*func2(3, 4, 5)) or have func1 check to see if args[0] was a list. Unfortunately, I can't use the first solution in this particular instance and to apply the second would require doing such a check in many places (there are a lot of functions in the role of func1 ).

Does anybody have an idea how to do this? I imagine some sort of introspection could be used, but I could be wrong.

You can consider writing function decorator that checks if the first argument is a list. Applying decorator to existing functions is a bit simpler than modifying functions.

You can use a Decorator as posted by Yaroslav.

Minimal example:

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)

Normally, I would just use func1(*func2(3, 4, 5)) or have func1 check to see if args[0] was a list . Unfortunately, I can't use the first solution in this particular instance and to apply the second would require doing such a check in many places (there are a lot of functions in the role of func1 ).

Why can't you use the first solution?

>>> 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
>>> 

If that wasn't possible, you could still have used func1(*tuple(func2(3, 4, 5))) (but you don't need to).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM