float
float

Reputation: 13

How can I merge two functions in one function?

Let there are some codes like

def f(a, b):
    # some code (no return)

def g(c, d, e):
    # some code (no return)

Then, I want to make a function "merge_functions" which

h = merge_functions(f, g)

works same with:

def h(a, b, c, d, e):
    f(a, b)
    g(c, d, e)

There could be more or fewer parameters in f and g, and I want to keep the name of the parameters the same.

There is no default value in any parameters.

I have tried:

from inspect import signature

getarg = lambda func: list(dict(signature(func).parameters).keys())
to_arg_form = lambda tup: ', '.join(tup)
def merge_functions(f, g):
    fl = getarg(f)
    gl = getarg(g)
    result = eval(f"lambda {to_arg_form(fl+gl)}:{f.__name__}({to_arg_form(fl)}) and False or {g.__name__}({to_arg_form(gl)})")
    return result

However, I could only use this function in the same file, not as a module.
How can I make the function that can also be used as a module?

Upvotes: 0

Views: 378

Answers (2)

quamrana
quamrana

Reputation: 39354

Ok, so I can make a function which will call the functions passed to it in order with the right number of parameters.

I'm not sure that getting the names of the parameters is possible in the general case: There may be functions you want to compose which have the same parameter names.

from inspect import signature

def merge_functions(*funcs):
    
    def composite(*args):
        new_args = args[:]
        for f in funcs:
            sigs = signature(f).parameters
            fargs = new_args[:len(sigs)]
            new_args = new_args[len(sigs):]
            f(*fargs)
            
    return composite

def f(a, b):
    print(f'Inside f({a},{b})')

def g(c, d, e):
    print(f'Inside g({c},{d},{e})')
    

h = merge_functions(f, g)

h(1,2,3,4,5)

Output:

Inside f(1,2)
Inside g(3,4,5)

Upvotes: 1

Hussein Awala
Hussein Awala

Reputation: 5096

You can try something like this code which creates a third function which you can use everywhere:

def f1(x1, x2, **args):
    print(f"{x1} {x2}")

def f2(x1, x3, x4, **args):
    print(f"{x1} {x3} {x4}")

def merge(f1, f2):
    return lambda **args: (f1(**args), f2(**args))

f3 = merge(f1, f2)

f3(x1=1, x2=2, x3=3, x4=4)

Upvotes: 1

Related Questions