-3

I want to use the default of a parameter, but include its name in the call. I thought that setting the parameter to None would do that, but it doesn't.

For example:

def a(num=3):
    print(num)

a(num=None) #returns "None", not "3" like I want it to.

How can I use the default of a named parameter while including it in the call? (Is it even possible?)

Just to explain why I would want to do something like this (since maybe it's a problem in my overall coding style):

I often times have code like this

def add(num, numToAdd=1):
    return num+numToAdd

def addTwice(num, numToAdd=None):
    for i in range(2):
        num=add(num, numToAdd=numToAdd)
    return num

addTwice(3) #throws an error instead of returning 5

What I want is for addTwice's numToAdd to always use the default of add's numToAdd, no matter what it is.

The reason: maybe later in the code I realize that it's better to add 2 as the default when executing add than it is to add 1.

So I change it to

def add(num, numToAdd=2):
        return num+numToAdd

But, this won't help anything unless I can always specify in addTwice to use the default if it receives a default.

So, that's the rationale.

In other words: I'm having a function (the first function) call another function (the second function), and if the first function has to use a default value, I want it to default to being the default value on the second function. That way, I only have to change the default value on the second function (not every single function that calls it as well) in order to change the default functionality.

Pro Q
  • 4,391
  • 4
  • 43
  • 92
  • 2
    If you include a default parameter, you don't need to mention it in the function call. Just do `a()`. – michaelpri Jun 06 '17 at 21:58
  • 1
    It prints None because you're explicitly passing the argument which overrides the default value – Andrew Li Jun 06 '17 at 21:59
  • Why do you want to pass a value and not use it? – cmd Jun 06 '17 at 22:07
  • 2
    I don't see why this is so heavily downvoted. It's a reasonable, well-written question. – user2357112 Jun 06 '17 at 22:07
  • @michaelpri See my explanation as to why I would want to do this... You are correct, but I don't want to have to program each explicit case for different combinations of default parameters. – Pro Q Jun 07 '17 at 00:55
  • @cmd updated the question to answer yours. Thank you. – Pro Q Jun 07 '17 at 00:55
  • Looks like you are misunderstanding what default params are for. What you should be doing in this case is create a variable in the function that has the value you "always want to use" and use that. – cmd Jun 20 '17 at 16:54
  • @cmd the default parameter just happens to be convenient to me, and I hope it will be for other people when I release the code. What value will be convenient to me will change, and I'll want it to change it in the code and have everything that uses the default change as well. – Pro Q Jun 21 '17 at 00:54

4 Answers4

4

There's no built-in support to explicitly use the default value of a parameter. If you don't want to leave the parameter out at the call site, you'd have to retrieve the default value very manually:

import inspect

a(num=inspect.signature(a).parameters['num'].default)

which wouldn't be worth it in most cases.

user2357112
  • 260,549
  • 28
  • 431
  • 505
2
def a(num=None):
    if num is None: 
       num = 3
    print(num)

a(num=None)  # prints 3
a() # prints 3

... I guess ... maybe

alternatively to explain default params

def a(num=3):
   print(num)

a(num=None) # prints None
a() # prints 3
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Yeah, this is how I've been defining most of my functions... It's just a hassle though, especially with a lot of parameters. – Pro Q Jun 07 '17 at 00:34
0

No, you can't: that's a contradiction in terms. The default value is used if and only if you do not supply a value in the arguments list. If you supply a value, then the default cannot be used within the routine.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

There is a great answer on how to do this (if you decide that the default-getting functionality I asked for is really what you want). But, I just wanted to point out that in practice I believe what I was trying to achieve is normally done with global variables.

That is, the usual way to do what I wanted to do is:

DEFAULT_NUM_TO_ADD = 1
def add(num, numToAdd=DEFAULT_NUM_TO_ADD):
    return num+numToAdd

def addTwice(num, numToAdd=DEFAULT_NUM_TO_ADD):
    for i in range(2):
        num=add(num, numToAdd=numToAdd)
    return num

addTwice(3) # returns 5

This allows me to quickly change the default, and the same default is used for both functions. It's explicit and very clear; it's pythonic.

Pro Q
  • 4,391
  • 4
  • 43
  • 92