Use Dictionary as Default Argument

So I am working on a python module, which is like a pipeline and contains lots of sub-modules. Each sub-module is a function which is flexible (like a plugin) and it needs some parameters. So the main-module receives every parameter from its arguments and pass it to each sub-module, and if it does not find a parameter in the argument, it passes a default value.

It looks like the following,

def main_module(pa1=1, pa2=2, pb1=3, pb2=4):
    sub_module_a(pa1, pa2)
    sub_module_b(pb1, pb2)

main_module(pa1=0, pb1=0)   # caller

But the problem is the sub-module may be changed at anytime and I do not want to change the interface for the main-module. And another problem is that after adding some modules the interface of the main-module will become very long and hard to maintain.

def main_module(pa1=1, pa2=2, pc1=5, pc2=6, pc3=7):
    sub_module_a(pa1, pa2)
    # I suddenly decide to use sub_module_c instead of sub_module_b
    # I will have to change the interface of main_module
    # and those who call it.
    sub_module_c(pc1, pc2, pc3)

main_module(pa1=0)    #Have to change caller

So finally I found a solution which looks like,

def main_module(parameter = {}):
    default_paramter = dict(
        pa1 = 1, 
        pa2 = 2,
        pb1 = 3,
        pb2 = 4,
    )
    default_parameter.update(parameter)
    sub_module_a(default_parameter['pa1'], default_parameter['pa2'])
    sub_module_b(default_parameter['pb1'], default_parameter['pb2'])

main_module({'pa1':0, 'pb1':0})

so that if I change the sub-module, the caller can still remain unchanged.

def main_module(parameter = {}):
    default_paramter = dict(
        pa1 = 1, 
        pa2 = 2,
        pc1 = 5,  # new parameters for sub_module_c
        pc2 = 6,
        pc3 = 7,
    )
    default_parameter.update(parameter)
    sub_module_a(default_parameter['pa1'], default_parameter['pa2'])
    sub_module_c(default_parameter['pc1'], default_parameter['pc2'])

main_module({'pa1':0, 'pb1':0})    # remain unchanged
# the caller doesn't even know
# that the implementation of main_module has changed

A even more fascinating way to support the plugin-style sub-modules is that

def main_module(module_list=[], parameter = {}):
    module_mapping = dict(
        use_module_a = sub_module_a,
        use_module_b = sub_module_b,
        use_module_c = sub_module_c,
    )
    default_paramter = dict(
        pa1 = 1, 
        pa2 = 2,
        pb1 = 3,
        pb2 = 4,
        pc1 = 5,  # new parameters for sub_module_c
        pc2 = 6,
        pc3 = 7,
    )
    default_parameter.update(parameter)
    
    for module in module_list:
        module_mapping[module](default_parameter)
        # but have to let the sub_modules pick 
        # the parameter they need in their implementation

# caller can decide which module it wants to use
main_module(['use_module_a', 'use_module_b'], {'pa1':0, 'pb1':0})

There are definitely many better ways to do it, and that’s why I think I am becoming to love Python – the flexibility.

Leave a Reply

Your email address will not be published.

− 5 = 5