Tom Walker
Tom Walker

Reputation: 857

Passing default parameters into nested functions python

I have a function

foo(x, setting1=def1, settings2=def2)

(actually this is a third party library function with a bunch of default parameters of which I need to set only 1 externally, but for the sake of example..)

I am calling this from

bar(y, settings2_in=def2)
   x = get_x(y)
   foo(x, settings2=settings2_in)

This is ok, but stylistically I'd rather call name the parameter settings2_in settings2. When I keep passing another layer down, I'll have to keep renaming the parameter, and it gets ugly.

bletch(z, settings2_in_2=def2)
   y = get_y(z)
   bar(y, settings2_in=settings_in_2)

Is there a "nice"/Pythonic way to pass a subset of default parameters down many layers of functions in this way?

Is Python clever enough to work out that if I do:

bar(y, settings2=def2)
   x = get_x(y)
   foo(x, settings2=settings2)

That the 2 uses of settings2 are different from the context?

Upvotes: 3

Views: 2516

Answers (2)

Chris Johnson
Chris Johnson

Reputation: 21946

To answer your question directly: yes, Python is clever enough to not confuse a local variable and an outbound function parameter with the same name. Example:

def x(a):
    ...

def y(a, b):
    return x(a=a)

In the return line, the right-hand a is the local variable from the parameter passed into function y and the left-hand a is the parameter to function x.

Names of parameters to called functions are in the namespace of the called function's parameter list, which is unrelated to the local and global variables of the calling context.

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140148

you could avoid redefining all the parameters in your functions, just use **kwargs to capture all keyword arguments.

Then pass the keyword arguments to your foo function

def foo(x, setting1="def1", settings2="def2"):
    print(setting1,settings2)


def bar(y,**kwargs):
    foo(y,**kwargs)

bar(12)
bar(y=12)
bar(12,setting1="other")

result:

def1 def2
def1 def2
other def2

note that since y is outside kwargs, passing y as keyword also works.

the only drawback is that you don't know what can be actually passed to bar, but it's logical as it depends on what foo accepts. Make that up by adding a docstring to your function.

Upvotes: 3

Related Questions