Non-Standard Optional Argument Defaults

11,616

Solution 1

def f(a,b,c=None):
    if c is None:
        c = g(b)

If None can be a valid value for c then you do this:

sentinel = object()
def f(a,b,c=sentinel):
    if c is sentinel:
        c = g(b)

Solution 2

You cannot do it that way.

Inside the function, check if c is specified. If not, do the calculation.

def f(a,b,c=None):
    if c == None:
        c = g(b)
    blabla

Solution 3

value of c will be evaluated (g(b)) at compilation time. You need g defined before f therefore. And of course you need a global b variable to be defined at that stage too.

b = 4

def g(a):
    return a+1

def test(a, c=g(b)):
    print(c)

test(b)

prints 5.

Solution 4

The problem with

sentinel = object()
def f(a, b, c=sentinel):
  if c is sentinel:
    c = g(b)

is that sentinel is global/public unless this code is part of a function/method. So someone might still be able to call f(23, 42, sentinel). However, if f is global/public, you can use a closure to make sentinel local/private so that the caller cannot use it:

def f():
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f()

If you are concerned that static code analyzers could get the wrong idea about f then, you can use the same parameters for the factory:

def f(a, b, c=object()): #@UnusedVariable
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f(23, 42)
Share:
11,616
ooboo
Author by

ooboo

Updated on June 09, 2022

Comments

  • ooboo
    ooboo about 2 years

    I have two functions:

    def f(a,b,c=g(b)):
        blabla
    
    def g(n):
        blabla
    

    c is an optional argument in function f. If the user does not specify its value, the program should compute g(b) and that would be the value of c. But the code does not compile - it says name 'b' is not defined. How to fix that?

    Someone suggested:

    def g(b):
        blabla
    
    def f(a,b,c=None):
        if c is None:
            c = g(b)
        blabla
    

    But this doesn't work. Maybe the user intended c to be None and then c will have another value.