PEP 8 has conflicting code examples (in my opinion), and I'm curious what the convention is for positioning closing braces.
Under the top of indentation they're on the same line as the parameters. Near the bottom it discusses positioning and instead says:
The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character of the last line of list[...] or it may be lined up under the first character of the line that starts the multiline construct[...]
which directly conflicts the code examples above.
Where do you commonly position your closing braces for multi-line statements, and what do you think is best practice in terms of convention?
Just for clarity, here are code examples which demonstrate the differences.
foo = long_function_name(
var_one, var_two,
var_three, var_four)
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
According to the PEP 8 standard, there are two ways to line up the closing braces, brackets, or parentheses. First, line it up with the first non-whitespace character of the previous line. Second, line it up with the first character that starts the multi-line construct. What is this?
Dictionaries are created in Python using curly braces. You can use curly braces to create both empty dictionaries and dictionaries that contain key-value pairs. Of course, you can always create dictionaries using the dict() method, but that way of creating dictionaries is not used very often.
One approach to check balanced parentheses is to use stack. Each time, when an open parentheses is encountered push it in the stack, and when closed parenthesis is encountered, match it with the top of stack and pop it. If stack is empty at the end, return Balanced otherwise, Unbalanced.
The open parenthesis, which looks like (, is used to begin parenthetical text. The close parenthesis, ), denotes the end of parenthetical text.
There's no conflict here, since PEP8 specifically says:
The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character of the last line of list, as in:
my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
or it may be lined up under the first character of the line that starts the multiline construct, as in:
my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( 'a', 'b', 'c', 'd', 'e', 'f', )
so both conventions are acceptable.
I personally prefer the latter convention, but that's just me.
The two sections you mention are different in that the first is about continuation lines that are followed by a block (such as a multiline def
or if
statement) while the second is about closing braces and parentheses on affectation and function calls. When starting a block, you wouldn't want to put the closing parenthesis at the beginning of the next line because going back to the original indentation conveys the end of the block. A few examples that clearly look odd:
def long_function_foo(
var_one, var_two, var_three,
var_four
):
print('This code really looks out of place')
def long_function_bar(
var_one,
var_two
):
print('and so does this one')
PEP8 allows what they call vertical alignment, and many examples in various PEPs use this convention which has become an automated feature of Python IDEs:
def long_function_name(var_one, var_two, var_three,
var_four, var_five):
"""Documentation would go here, which makes it look better."""
print(var_one + var_two + var_three)
But I personally avoid it. This is an opinion-based topic, but I don't like relying on alignment through a specific number of spaces. It's tedious to maintain and relies too much on IDE smart indents. I prefer this notation, which is allowed by PEP8 but doesn't seem as popular. Note the double-indent used for distinction from the function body:
def long_function_name(
alpha, bravo, charlie, delta, echo, foxtrot,
hotel, indiana):
"""Documentation would go here."""
print(var_one + var_two + var_three)
When it comes to function calls and assignments, PEP8 doesn't have a clear answer. One might indent the closing parenthesis, as a way to mimic how blocks end when the next instruction is less indented.
foo = bar(
1, 2, 3
)
Vertical alignment is very popular and I'll admit it looks good, but again I don't want to force indentation size on future readers of my code so I avoid this:
foo = bar(1, 2, 3, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14)
Or one can also put the closing brace/parenthesis aligned to the left:
foo = bar(
1, 2, 3
)
Coming from a C++, Java and JavaScript background, I use the latter option. Technically, you could also put the closing parenthesis on the same line as the arguments, but then it makes it look like an indented code block too much for my tastes, and it's not something I've really seen people do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With