0
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.

hasleron
  • 499
  • 3
  • 10
  • What about `__init__(self, **kwargs)` and then `a = A(**vars(args))` – jvx8ss Oct 31 '22 at 14:19
  • Consider whether the class needs a default argument at all, since you are going to provide something resulting from the argument parser anyway. – chepner Oct 31 '22 at 14:22
  • It's only redundant if your definition of `A` is too tightly coupled to a particular script that uses it. – chepner Oct 31 '22 at 14:23

1 Answers1

0
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

hasleron
  • 499
  • 3
  • 10