使用 Python 关闭大括号

问题描述 投票:0回答:4

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

多行结构上的右大括号/方括号/括号可以 要么在最后一个的第一个非空白字符下排队 list[...] 的行,或者它可以排列在列表的第一个字符下 开始多行构造的行[...]

这与上面的代码示例直接冲突。
您通常将多行语句的右大括号放在哪里,您认为就惯例而言最佳实践是什么?

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

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',
)
python pep8 convention
4个回答
7
投票

您提到的两个部分的不同之处在于,第一个部分是关于后面跟着一个块的连续行(例如多行

def
if
语句),而第二个部分是关于赋值和函数调用时的右大括号和括号。当开始一个块时,您不希望将右括号放在下一行的开头,因为返回到原始缩进会传达块的结尾。一些看起来显然很奇怪的例子:

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 IDE 的自动化功能:

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)

或者也可以将右大括号/括号左对齐:

foo = bar(
    1, 2, 3
)

由于拥有 C++、Java 和 JavaScript 背景,我使用后一种选择。从技术上讲,您也可以将右括号与参数放在同一行,但这使它看起来像一个缩进的代码块,太不符合我的口味,而且这不是我真正见过人们这样做的事情。


5
投票

这里没有冲突,因为PEP8特别说:

多行结构上的右大括号/方括号/圆括号 可以 任一 在最后一个的第一个非空白字符下排列 列表行,如:

my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )

它可能会排列在该行的第一个字符下方 启动多行构造,如下所示:

my_list = [
    1, 2, 3,
    4, 5, 6,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
)

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

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


3
投票

这是来自 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]

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


0
投票

我们都同意,与其他编程语言不同,Python 使用缩进来指示代码块中语句的层次结构和分组,并通过缩进连续行来存档。

现在我不明白为什么多行结构上的右大括号/方括号/圆括号不属于这一类别,因为它们显然属于第一行的初始赋值。让我们看一个现实世界的例子来说明为什么这很重要:

import pandas as pd # unpythonic and unfoldable: def import_data_from_csv_v1( file_path: str ) -> pd.DataFrame: """Read a CSV file and return a DataFrame.""" df = pd.read_csv( file_path, parse_dates=['date'] ).set_index('date').groupby('region').sum() return df # readable and foldable: def import_data_from_csv_v2( file_path: str ) -> pd.DataFrame: """Read a CSV file and return a DataFrame.""" df = pd.read_csv( file_path, parse_dates=['date'] ).set_index('date').groupby('region').sum() return df

第二个示例中的缩进清楚地表明了哪些行属于在一起。函数结果的类型注释与参数是函数定义的同等部分。这同样适用于 pandas 方法链接:这只是一个分配,而不是两个。

但是,如果您想通过使用代码折叠来简化模块中的导航,那么不正确的缩进会变得非常烦人。 VS 代码。它根本不适用于该功能的第一个版本!

因此,如果可读性对您很重要,请将多行结构上的右大括号/方括号/括号放在最后一行的第一个非空白字符下,而不是其他任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.