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

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

什么是更好的做法?

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

要么

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

以下情况如下:

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

要么

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

?

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

python function coding-style parameter-passing
4个回答
33
投票

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

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

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

例如,这样的函数:

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

......这样叫:

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

...然后改为:

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

在git中生成这个diff:

$ 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中生成这个diff:

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

12
投票

在数据结构中,尾随逗号对于更容易添加项目是“有用的”:

a = [
      1,
      2,
      3,
    ]

更容易改变

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

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

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


7
投票

我也会留下我的2美分,即使这个帖子已经在这里待了一段时间,它可能会让某人受益:)

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

没有:

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

是:

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

函数调用中的用法(谨慎使用从不),原因如下:


  • 编码原则之一是函数应该做一件事,而只做一件事。因此,在那里看到一个尾随的逗号,当他们真的不应该时,可能会出现很多问题。通常当你在某个地方看到一个尾随的逗号时,你会希望这个东西随着时间的推移而改变。因此,如果它是一个列表,元组,字典等,它通常表示无论是谁设计它,都是为了在该结构中物理添加或删除或切换行,并且......你没有看到它与函数那么多,或者至少你不应该,如果你这样做,应该考虑更好的设计。
  • 如前所述,一个功能也应该是非常可预测的,你没有设计一个函数同时向月球发送邮件和火箭,并在打电话发送邮件时留下一个逗号,因为谁知道你何时可以发送火箭并且你想要更少杂乱的差异(它只会导致更多的混乱和糟糕的设计)
  • 任意数量的参数(或者甚至是固定的,但是大量的参数)通常表示您要在那里实例化一个对象,或者您正在做多个事情,而当您真正应该做的是将您的设计拆分为创建多个较小的参数时函数,每个都做一件事,因此,不需要尾随逗号。
  • 还要考虑,即使你确实有一个函数,你可以调用多个参数,想想你多久会这样做以及它意味着什么?那么这意味着: 它意味着在调用位置重构代码(可能在另一个函数中,或在模块中或某个地方),因为通常函数的结果存储在变量中,并且您需要使用该新结果,这意味着重构。 如果它不暗示重构那么它意味着函数不返回任何东西,或者它确实返回相同的东西,在这种情况下它意味着它使用调用中传递的额外参数做多个事情,如前所述,不是很理想。 即使您不关心编码原则,并忽略上述内容,这种情况多久会完成一次?如果经常给出答案,那就是另一个糟糕,不稳定的设计实现。如果它不经常(好吧,它本身就应该解决它不应该存在,即使你认为它应该,我认为你的眼睛可以在版本控制差异中承受另外一行,这样你就可以避免在同样分享您项目的人员队伍中引起额外的混淆。

实际用途


  • 跟踪逗号是有道理的,就像你在数据结构中所说的那样,预计会随着时间的推移在物理上发生变化的数据结构,因为如果你在运行时更改它,那么它对编辑器中的任何内容都没有任何意义,除了这个定义可能是一个空结构[] xD
  • 在预期数据结构(列表,字符串,集合,元组等)发生变化(物理上,源代码)的情况下,实际上建议使用尾随逗号并且实际上有用(see the full PEP link,它有用例和建议)

结论:


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

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”。始终添加逗号可避免此错误来源。

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

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