Search code examples
pythonfunction-composition

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.


Solution

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