Search code examples
pythonpep8

What's the 'cleanest' way to indent multiple function arguments considering pep8?


I am wondering what's the best way to format a function with multiple arguments.

Suppose I have a function with many arguments with potentially long argument names or default values such as for example:

def my_function_with_a_long_name(argument1="this is a long default value", argument2=["some", "long", "default", "values"]):
    pass

Naturally, I would try to make the function more readable. Following the pep8 styling guide https://peps.python.org/pep-0008/ I have multiple options to format such function:

I can use a hanging indent with extra indentation of the arguments:

def my_function(
        a="a",
        b="b",
        c="c"):
    pass

I could also put the first argument on the first line and align the following arguments with it:

def my_function(a="a",
                b="b",
                c="c"
                ):
    pass

My linter also accepts the following option, though I'm not sure it is in agreement with pep8:

def my_function(
    a="a",
    b="b",
    c="c"
):
    pass 

None of these options looks 100% 'clean' to me. I guess the first option seems cleanest though it bothers me a bit to have the parenthesis on the same line as the last argument. However, putting the parenthesis on an extra line seems to conflict with pep8:

def my_function(
        a="a",
        b="b",
        c="c"
    ):
        pass

Now I am wondering, while multiple options might be acceptable if we only consider pep8, is there one option that is generally agreed on in the python community? Are there arguments for or against any of these options or does just come down to personal preference?

In a collaborative project, which option would you choose and why?


Solution

  • If pep8 doesn't strictly say that you have to use this style, you're free to choose between correct ones.

    But why bothering yourself to format it manually? The only important thing is to be consistent in your code. So just leave it to a formatter. That takes care of it.

    I would suggest Black. Written by a core developer - Łukasz Langa

    It formats your function to:

    def my_function_with_a_long_name(
        argument1="this is a long default value",
        argument2=["some", "long", "default", "values"],
    ):
        pass