Search code examples
pythonargparse

Avoid redundancy in argparse defaults


import argparse

class A:
    def __init__(self,val=1):
        self.val = val

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--val', default=1)
    args = parser.parse_args()

    a = A(val=args.val)

Quite often I find myself with a structure as shown above, where a class takes an optional argument with a default value. For the argparse I need to define this default value again. If it changes, I have to change it in multiple spots.

Leaving the default value in the class is not an option, as the class might be initialised from somewhere else as well.

I considered to set the argparse default value to None and only pass it when it's not None, but with multiple variables that will lead to convoluted code.

The only other thing coming to my mind is a section on the top of the page to set constants like "DEFAULT_val" so the defaults are defined only once, but I'm wondering if there's a better solution.


Solution

  • import argparse
    import inspect
    
    def get_default_args(func):
        signature = inspect.signature(func)
        return {
            k: v.default
            for k, v in signature.parameters.items()
            if v.default is not inspect.Parameter.empty
        }
    
    class A:
        def __init__(self,val=1):
            self.val = val
    
    if __name__ == '__main__':
        default_values = get_default_args(A.__init__)
    
        parser = argparse.ArgumentParser()
        parser.add_argument('--val', default=default_values['val'])
        args = parser.parse_args()
    
        a = A(val=args.val)
    

    Found the solution in the answers to another question