Pedia
Pedia

Reputation: 1492

How to explicitly indicate usage of default value of a named argument in a python function?

Is it possible to explicitly tell a function in python to use the default value of a parameter ?

For instance, if a function is defined as:

def foo(a=1, b=2, c=3):
    pass

I would like to call the function like:

foo(a=3, b=<USE-DEFAULT>, c=10)
                ^
                |

which should be equivalent to:

foo(a=3, c=10)

One usage example is if a function is used to instantiate an instance of a class:

class foo():
    def __init__(a=1, b=2, c=3):
       self.a = a
       self.b = b
       self.c = c

def create_foo(a=None, b=None, c=None):
    f = foo( <PASS ALL EXCEPT NONE> )

F = create_foo(a=10, c=30)
# Then F should have a=10, b=2, c=30

In this example, I would like to avoid defining default values multiple times.

Upvotes: 2

Views: 1220

Answers (3)

hajef
hajef

Reputation: 334

If you don't use *args and **kwargs and subclassing there is no reason to explicitly call the defaults and as long as you are using only your own classes and you don't need mutual default arguments, you can just hand over the same values as the defaults - BUT if you are working with *args and **kwargs and the method to be called is from a super class, you might get problems with the MRO. (See this article for further information: https://www.python.org/download/releases/2.3/mro/)

The only way I know to prevent a(n at this moment unknown) super class to pass an argument to the class your calss extends is to call the method explicidly and than hand over only the arguments you want it to get.
I don't see another use case for an explicit default call.

Upvotes: 2

languitar
languitar

Reputation: 6784

Just call that functions as

foo(a=3, c=10)

Alternatively, you could use the following approach, which is e.g. necessary for lists, because default values are evaluated in the module scope:

def foo(a=None, b=None, c=None):
    local_a = a or "default"
    ...

foo(a=42, b=None, c=16)

None then encodes to use the default, if None is no valid option.

Finally, you could just defined the defaults as "constants":

DEFAULT_A = 42
DEFAULT_B = "foo"
DEFAULT_C = 17

def foo(a=DEFAULT_A, b=DEFAULT_B, c=DEFAULT_C):
    pass

foo(16, DEFAULT_B, 123)

But this is quite uncommon.

For you updated example, I would propose to use * and ** operators:

def create_foo(*args, **kwargs):
    f = foo(*args, **kwargs)

create_foo(42, b="non-default")

See this question for explanations how these operators work.

Upvotes: 4

JkShaw
JkShaw

Reputation: 1947

When defining function, you can set the default value, so when you call the function you do not need to pass the default argument to the function.

def foo(a=1, b=<USE-DEFAULT>, c=3):
    print(b)

foo(a=3, c=10)

In above function foo, you are actually setting the default value for all arguments a, b, c

example:

>>> def foo(a=1, b=2, c=3):
...     print('a: {0}, b: {1}, c: {2}'.format(a, b, c))
... 
>>> foo(a=3, c=10)
a: 3, b: 2, c: 10
>>> foo()
a: 1, b: 2, c: 3
>>> foo(a=3)
a: 3, b: 2, c: 3
>>> foo(a=3, c=10, b=5)
a: 3, b: 5, c: 10
>>> 

Upvotes: 0

Related Questions