我应该在函数调用中的最后一个参数后添加一个尾随逗号吗?

时间:2012-08-23 08:34:27

标签: python function coding-style parameter-passing

最好做什么?

self.call(1, True, "hi")

self.call(1, True, "hi",)

以下情况如下:

self.call(
    1,
    True,
    "hi"
)

self.call(
    1,
    True,
    "hi",
)

在数据结构中添加尾随逗号的原因对我来说很熟悉,但是函数调用呢?

5 个答案:

答案 0 :(得分:32)

我认为没有技术上的理由可以避免在函数调用中使用逗号,但有些人可能会发现它们会分散注意力。有些人可能会停下来说:

“嗯,我想知道那真的应该在那儿吗?”

我毫不犹豫地称这是一个好处,但是使用尾随逗号和缩进样式的效果以使版本控制差异看起来更清晰添加一个参数。

例如,像这样的函数:

def my_fun(a, b, c=None):
    ...

......这样叫:

my_fun(
    a='abc',
    b=123
)

...然后改为:

my_fun(
    a='abc',
    b=123,
    c='def'
)

在git中生成这个差异:

$ git diff
...
 my_fun(
     a='abc',
-    b=123
+    b=123,
+    c='def'
 )

然而,

my_fun(
    a='abc',
    b=123,
)

改为......

my_fun(
    a='abc',
    b=123,
    c='def',
)

在git中生成这个差异:

$ git diff
...
 my_fun(
     a='abc',
     b=123,
+    c='def',
 )

答案 1 :(得分:12)

在数据结构中,尾随逗号“非常有用”,可以更轻松地添加项目:

a = [
      1,
      2,
      3,
    ]

更容易变成

a = [
      1,
      2,
      3,
      4,
      5,
    ]

因为您不必编辑显示3,的行。

但是函数调用没有这样的好处,通常不会改变长度。所以我不鼓励使用尾随逗号。

答案 2 :(得分:7)

我也会在这里留下2美分,即使这个帖子已经存在了一段时间,也可能对某人有益:)

PEP8 实际上确实说when to use trailing commas如果您遵循他们的推荐(不是强制性的,但绝对是推荐),那么您的第二个单行示例可以被排除在外,即:

没有

self.call(1, True, "hi",)

是:

self.call(
    1,
    True,
    "hi",
)

函数调用中的用法(谨慎使用,从不),这就是原因:

  • 编码原则之一是功能应该一件事一件事。因此,在那里看到一个尾随的逗号,当他们真的不应该时,可能会出现很多问题。通常,当您在某处看到一个尾随逗号时,期望随时间变化。因此,如果它是列表元组字典等,它通常表示无论是谁设计它,都是为了实际添加或删除或切换该结构中的线条,以及......你没有看到功能那么多,或者至少你不应该这样做,如果你这样做,应该考虑更好的设计。

  • 如前所述,功能也应该是非常可预测的,你不设计一个功能,同时向月球发送邮件和火箭,并留下尾随逗号打电话发邮件是因为谁知道你什么时候发送火箭而且你想要更少混乱的差异(这只会造成更多的混乱和糟糕的设计)

  • 任意数量的参数(或者甚至是固定但大量的参数)通常表示您要在那里实例化一个对象,或者做多个事情,当你真正应该做的就是将你的设计分成几个较小的功能,每个都做一件事,因此,不需要尾随的逗号

  • 还要考虑,即使你确实有一个函数,你可以用多个参数调用它,想想你多久会这样做以及它意味着什么?好吧,这意味着:

    • 它意味着在调用位置重构代码(可能在另一个函数中,或在模块中或某个地方),因为函数的结果通常存储在变量中,您需要使用该新结果,这样就可以了意味着重构。
    • 如果它不暗示重构,那么它意味着函数不返回任何内容,或者它确实返回相同的东西,在这种情况下,它意味着它使用调用中传递的额外参数执行多项操作,如前所述,并不是很理想。
    • 即使您不关心编码原则,也忽略了上述内容,这种情况多久会完成一次?如果经常给出答案,那就是另一个糟糕,不稳定的设计实现。如果它不经常(好吧,它本身就应该解决它不应该存在,即使你认为它应该,我认为你的眼睛可以在版本控制差异中承受另外一行,这样你就可以避免在分享你的项目的人的队伍中造成额外的混乱。

实际用法

  • 尾随逗号有意义,就像您在数据结构中所说的那样,预计会随着时间的推移而发生物理变化的数据结构,因为如果您在运行时更改它,那么就不会t对编辑器中的任何内容都有意义,除了可能是空结构的定义[] xD

  • 在预期数据结构(列表,字符串,集合,元组等)发生变化的情况下(物理上,源代码),实际上建议使用尾随逗号并且实际上有用({{ 3}},它有用例和建议)

结论:

  • 推荐在预期会发生物理变化的多行数据结构中
  • 在函数调用中很少会永远
  • 从不在函数定义

答案 3 :(得分:4)

我认为,在这个问题上,同样的理由适用于列表和元组,因为函数参数列表就是这样。

以下是针对该语言(c.f.)的设计决策的常见问题解答引用:

  

为什么Python在列表和元组末尾允许使用逗号?

     

Python允许您在列表,元组和词典的末尾添加一个尾随逗号:

[1, 2, 3,]
('a', 'b', 'c',)
d = {
    "A": [1, 5],
    "B": [6, 7],  # last trailing comma is optional but good style
}
     

有几个理由允许这样做。

     

如果列表,元组或字典的文字值分布在多行中,则更容易添加更多元素,因为您不必记住在上一行中添加逗号。这些行也可以重新排序,而不会产生语法错误。

     

意外省略逗号可能会导致难以诊断的错误。例如:

x = [
  "fee",
  "fie"
  "foo",
  "fum"
]
     

这个列表看起来有四个元素,但它实际上包含三个:“费用”,“fiefoo”和“fum”。始终添加逗号可以避免此错误来源。

     

允许尾随逗号也可以使程序代码生成更容易。

答案 4 :(得分:0)

这是特定于工具的,但实际上,即使在单行函数参数列表中,它实际上也使在vim / Gvim中的代码重构更加容易。

  

def foo(a,b,c,e,d,):

更改为

  

def foo(a,b,c,d,e,):

使用vim时,只需将两个击键(dW)移至要粘贴的位置并按(p)即可删除“ e”或“ d”。

如果您没有逗号结尾,则最终必须将其从新的最后一项中删除并将其添加到旧的最后一项中。或者,您必须更小心地删除,直到逗号为止并更精确地粘贴。到处都有逗号,您可以将所有内容视为统一的块,可以轻松交换。

Vim在python编写者中显然很受欢迎,因此它实际上似乎有一些优点:https://www.sitepoint.com/which-code-editors-do-pythonists-use/