Search code examples
pythonfunctiondefaultdefault-valuekeyword-argument

trigger default keyword arg in function python


Is it possible to trigger the default keywork argument of a function in some special cases ? In particular in this example:

def funcA(a, data='dataset1'):
    ... # function code
def funcB(a, b, c, data='dataset42'):
    ... # function code

def func_global(a, b, c, data):
   funcA(a, data=data)
   funcB(a, b, c, data=data)

# standard use, funcA and funcB use dataset5
func_global(1,2,3, data='dataset5')

# desired use : funcA and funcB use the dataset from their default kwarg
func_global(1,2,3, data='default') # this obviously wont work as will call the dataset called 'default'

# what I  want to avoid because I have a lot of functions (A,B,C,...), and I don't want to duplicate:

def func_global(a, b, c, data):
   if data == 'default':
       funcA(a)
       funcB(a, b, c)
   else:
       funcA(a, data=data)
       funcB(a, b, c, data=data)

Also a constraint: I cannot change the funcA or funcB. if you have any suggestion how to avoid the duplication, thanks a lot


Solution

  • You can use a decorator:

    def default_data(func):
        def f(*args, **kwargs):
            if 'data' in kwargs and kwargs['data'] == 'default':
                del kwargs['data']
            return func(*args, **kwargs)
        return f
    

    Now you need to decorate your functions and simplify func_global

    funcA = default_data(funcA)
    funcB = default_data(funcB)
    
    def func_global(a, b, c, data):
        funcA(a, data=data)
        funcB(a, b, c, data=data)
    

    If you have access to the code of funcA and funcB then you can simply decorate them with @default_data:

    @default_data
    def funcA(a, data='dataset1'):
        ... # function code
    
    @default_data
    def funcB(a, b, c, data='dataset42'):
        ... # function code