用 Python 结束大括号

Closing braces with Python

PEP 8 有相互冲突的代码示例(在我看来),我很好奇定位右大括号的约定是什么。
indentation 的顶部,它们与参数在同一行。在底部附近,它讨论了定位,而是说:

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[...]

这与上面的代码示例直接冲突。
对于多行语句,您通常将右大括号放在什么位置?您认为在约定方面的最佳做法是什么?

为清楚起见,以下是演示差异的代码示例。

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',
)

这里没有冲突,因为PEP8具体说:

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',
)

所以两种约定都是可以接受的。

我个人更喜欢后一种约定,但这就是我。

您提到的两个部分的不同之处在于,第一个是关于连续行,后面是一个块(例如多行 defif 语句),而第二个是关于关闭矫揉造作和函数调用上的大括号和圆括号。当开始一个块时,您不希望将右括号放在下一行的开头,因为返回到原始缩进表示块结束。几个明显看起来很奇怪的例子:

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 允许他们所谓的垂直对齐,各种 PEP 中的许多示例都使用此约定,这已成为 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)

但我个人是避免的。这是一个基于意见的主题,但我不喜欢依靠特定数量的空间对齐。维护和过度依赖 IDE 智能缩进很乏味。我更喜欢这种表示法,它是 PEP8 允许的,但似乎并不流行。注意用于与函数体区分的双缩进:

def long_function_name(
        alpha, bravo, charlie, delta, echo, foxtrot,
        hotel, indiana):
    """Documentation would go here."""
    print(var_one + var_two + var_three)

谈到函数调用和赋值,PEP8 没有明确的答案。人们可能会缩进右括号,作为一种模仿下一条指令缩进较少时块如何结束的方式。

foo = bar(
    1, 2, 3
    )

垂直对齐非常流行,我承认它看起来不错,但我不想对我的代码的未来读者强制缩进大小,所以我避免了这种情况:

foo = bar(1, 2, 3, 5, 6, 7, 8, 9,
          10, 11, 12, 13, 14)

或者也可以将结尾 brace/parenthesis 左对齐:

foo = bar(
    1, 2, 3
)

来自 C++,Java 和 JavaScript 背景,我使用后一个选项。从技术上讲,您也可以将右括号与参数放在同一行,但这样会使它看起来像一个缩进代码块,对我来说太过分了,而且我真的没有见过人们这样做。

这是来自 google 的 tensorflow 和 facebook 的 pytorch 的两个代码片段。

张量流

if (not input_saved_model_dir and
      not saver_lib.checkpoint_exists(input_checkpoint)):
    print("Input checkpoint '" + input_checkpoint + "' doesn't exist!")

火炬

ALL_TENSORTYPES = [torch.float,
                   torch.double,
                   torch.half]

两者都使用了同一行右大括号策略。所以,在我看来,最好遵循这一点。