0

What's a good way to handle lots of parameters using standard python modules & techniques when creating a function in a module that can be called from the command line or imported and called programmatically?

For example:

# my_thing.py
import argparse

def my_thing(
        param1=None, param2=None,
        param3=None, param4=None,
        param5=None, param6=None,
        param7=None, param8=None):
    # Do something with all those parameters
    pass

def main():
    parser = argparse.ArgumentParser()
    # add arguments
    args = parser.parse_args()

    my_thing(
        param1=args.param1, param2=args.param2,
        param3=args.param3, param4=args.param4,
        param5=args.param5, param6=args.param6,
        param7=args.param7, param8=args.param8):

if __name__ == "__main__":
    main()

or maybe this...

# my_thing.py
import argparse

def my_thing(params):
    # Do something with all those parameters
    pass

def main():
    parser = argparse.ArgumentParser()
    # add arguments
    args = parser.parse_args()

    params = {
        "param1":args.param1, "param2":args.param2,
        "param3":args.param3, "param4":args.param4,
        "param5":args.param5, "param6":args.param6,
        "param7":args.param7, "param8":args.param8}

    my_thing(params)

if __name__ == "__main__":
    main()
marcj
  • 1
  • 1

3 Answers3

0

It may not be the BEST way, but you could store all the parameters in a dictionary, or order them in a list.

#dictionary
def my_thing(dict):
    param_1 = dict['param_1']
    param_i = dict['param_i']

# list
def my_thing(list_of_param):
    param_1 = list_of_param[0]
    ...param_i = list_of_param[i]...

A better way would be to create a wrapper object to encapsulate the parameters, but none of those really help for ease of creating new instances.

To create new instances quickly it may help to store the parameters in a .txt or .csv file and parse the file for the different parameters. This would make it easy to run in the command line because you could easily add the file as one of the arguments.

python my_script.py my_parameters.txt
Jake
  • 617
  • 1
  • 6
  • 21
0

You can actually use a third option, passing the __dict__ attribute of the Namespace object that parser.parse_args() returns, into my_thing. object.__dict__ accesses the underlying dictionary that all objects use to store their attributes. In this case, the attributes of the Namespace object are the command line arguments that are provide to the script.

# my_thing.py
import argparse


def my_thing(params):
    print(params)


def main():
    parser = argparse.ArgumentParser()
    # add arguments
    args = parser.parse_args()
    my_thing(args.__dict__)


if __name__ == "__main__":
    main()
Christian Dean
  • 22,138
  • 7
  • 54
  • 87
0

How about using keyword-only arguments?

For example:

import argparse

def my_thing(*, param1, param2, param3):
    # Do something with all those parameters
    pass

def main():
    parser = argparse.ArgumentParser()
    # add arguments
    args = parser.parse_args()

    # see https://stackoverflow.com/q/16878315/5220128
    my_thing(**vars(args))

if __name__ == "__main__":
    main()