1

I currently have a function with many optional arguments, something like this:

def many_argument_function(required1, required2, optional1=1, optional2=2,
                           optional3=None, optional4="Test", optional5="g",
                           optional6=2, optional7=(0, 255, 0), optional8=0.5):
                           # Do stuff

But in reality, it has over 20 optional arguments which take five lines even with 120 character line limit.

Is there a design pattern to simplify this/make it prettier?

P.S. I have considered making a separate configuration file for this function, but then calling it would be annoying since most of the time only one or two optional arguments are used.

EDIT1: I don't want to use kwargs as I want names of arguments and default values visible in my IDE (PyCharm)

Rizhiy
  • 775
  • 1
  • 9
  • 31
  • Possible duplicate of [Is there a way to pass optional parameters to a function?](https://stackoverflow.com/questions/14017996/is-there-a-way-to-pass-optional-parameters-to-a-function) – stovfl Sep 24 '18 at 16:31
  • I don't want to use `kwargs` as I want names and default values visible in IDE – Rizhiy Sep 24 '18 at 16:34
  • couldn't you put your optionals into a list and pass the list – vash_the_stampede Sep 24 '18 at 16:35
  • @vash_the_stampede In python if you have a list as a default for an argument it is mutable, so can't do that. – Rizhiy Sep 24 '18 at 16:37
  • No i'm saying don use a default and just pass a list containing all the default variables, if you have changes you can make a list copy with the change, and pass that – vash_the_stampede Sep 24 '18 at 16:38
  • but eh that would be work too – vash_the_stampede Sep 24 '18 at 16:38
  • Passing the list is not optimal since the user would need to create it first, which is annoying. – Rizhiy Sep 24 '18 at 16:41
  • What im saying is say you have a list with values and then you can use a loop to change a specific option in that list then pass that list with the modified option, but even so yes too much work – vash_the_stampede Sep 24 '18 at 16:43
  • The usual way I've seen this handled (in libraries like NumPy or Pandas) is to really just write out all the parameters across a ton of lines the way you're already doing it. – user2357112 Sep 24 '18 at 16:43
  • Assuming your function actually *needs* 20 different optional parameters, I don't see a problem with listing them one per line in the definition. What is likely is you could aggregate some of the arguments into one or more classes, so that some parameters in the new definition incorporates two or more of the old parameters. For instance, `optional7` is already a tuple rather than 3 separate parameters for (I assume) red, green, and blue individually. – chepner Sep 24 '18 at 16:44
  • [NumPy example](https://github.com/numpy/numpy/blob/v1.15.1/numpy/lib/npyio.py#L1500-L2182), [Pandas example](https://github.com/pandas-dev/pandas/blob/v0.23.4/pandas/io/parsers.py#L542-L678). – user2357112 Sep 24 '18 at 16:44
  • @user2357112 is actually HAL 9000, goodmorning overlord – vash_the_stampede Sep 24 '18 at 16:48

1 Answers1

6

There's nothing wrong with just listing one parameter per line.

def many_argument_function(
        required1,
        required2,
        optional1=1,
        optional2=2,
        optional3=None,
        optional4="Test",
        optional5="g",
        optional6=2,
        optional7=(0, 255, 0),
        optional8=0.5
    ):

    """
    This function does some stuff.
    """

    # Do stuff

PEP 8 endorses this style of indentation, and although its own example puts multiple parameters on a single line, I find it much easier to scan a large list of parameters if each is on its own line.

chepner
  • 497,756
  • 71
  • 530
  • 681