Pythonic solution for conditional arguments passing

Going by the now-deleted comments to the question that the check is meant to be for the variables being None rather than being falsey, change func so that it handles the arguments being None:

def func(a=None, b=None):
   if a is None:
      a = 0
   if b is None:
      b = 10

And then just call func(a, b) every time.


If you don't want to change anything in func then the sensible option would be passing a dict of arguments to the function:

>>> def func(a=0,b=10):
...  return a+b
...
>>> args = {'a':15,'b':15}
>>> func(**args)
30
>>> args={'a':15}
>>> func(**args)
25
>>> args={'b':6}
>>> func(**args)
6
>>> args = {}
>>> func(**args)
10

or just:

>>>func(**{'a':7})
17

to solve your specific question I would do:

args = {'a' : a, 'b' : b}
for varName, varVal in args.items():
    if not varVal:
        del args[varName]
f(**args)

But the most pythonic way would be to use None as the default value in your function:

f(a=None, b=None):
    a = 10 if a is None else a
    ...

and just call f(a, b)


You can add a decorator that would eliminate None arguments:

def skip_nones(fun):
    def _(*args, **kwargs):
        for a, v in zip(fun.__code__.co_varnames, args):
            if v is not None:
                kwargs[a] = v
        return fun(**kwargs)
    return _

@skip_nones
def func(a=10, b=20):
    print a, b

func(None, None) # 10 20
func(11, None)   # 11 20
func(None, 33)   # 10 33

Tags:

Python