Search code examples
pythonpython-3.6python-decorators

Passing arguments to a Python function within a function


In the case shown below I have a function titled func1() that resides in func3(), where func3() is solving for the value of an ODE using the Euler method.

def func1(x, y):
    return y * np.log(y) / x

def func3(x, y, step_size, func):
    dydx = func(x, y)
    new_x = x + step_size
    new_y = y _ step_size * dydx
    return new_x, new_y

step_size - 0.1
lower = 2.0
upper = 3.0
e = 2.7182828284

x_val = [2.0]
y_val = [e]
for i in range(10):
    x, y = func3(x_val[i], y_val[i], step_size, func1)
    x_val.append(x)
    y_val.append(y)

The code is passing func1 to func3 as a decorator and writing the output to a list as it iterates over the range of 0 to 10. However, the code inside func3() is hardcoded to the exact input of func1(), which is x and y. I would like to write func3() to be generic enough that you can pass any function to it as long as its first two inputs are x and y, but it should be cabaple of taking more inputs. So assume that all the code shown above was identical, but instead of passing func1(), I passed func2() to func3(), with the structure whown below.

def func2(x, y, z):
    return z * y * np.log(y) / (x*z)

How could I write func3() to be generic enough that it could take either of the two functions and understand that their are more arguments to pass to func1(), which would also have to be passed into func3()?


Solution

  • You can use Python's variable-length argument syntax to await any extra arguments, and pass them on. If there are none, it works anyway: The starred variable will receive the empty list as its value, and will disappear when expanded in the fall to func.

    def func1(x, y):
        return x+y
    
    def func2(x, y, z):
        return (x+y)*z
    
    def caller(func, x, y, other, other2, *args):
        return func(x, y, *args)