122

为什么PEP 8 建议=在关键字参数或默认参数值中不要有空格?

=这是否与在 Python 代码中每隔一个出现的地方推荐空格不一致?

怎么:

func(1, 2, very_long_variable_name=another_very_long_variable_name)

优于:

func(1, 2, very_long_variable_name = another_very_long_variable_name)

任何指向 Python 的BDFL讨论/解释的链接将不胜感激。

请注意,这个问题更多的是关于 kwargs 而不是默认值,我只是使用了 PEP 8 中的措辞。

我不是在征求意见。我在问这个决定背后的原因。这更像是问我为什么要在 C 程序中的语句{与语句在同一行使用,而不是我是否应该使用它。if

4

7 回答 7

83

I guess that it is because a keyword argument is essentially different than a variable assignment.

For example, there is plenty of code like this:

kw1 = some_value
kw2 = some_value
kw3 = some_value
some_func(
    1,
    2,
    kw1=kw1,
    kw2=kw2,
    kw3=kw3)

As you see, it makes complete sense to assign a variable to a keyword argument named exactly the same, so it improves readability to see them without spaces. It is easier to recognize that we are using keyword arguments and not assigning a variable to itself.

Also, parameters tend to go in the same line whereas assignments usually are each one in their own line, so saving space is likely to be an important matter there.

于 2012-01-13T15:40:43.483 回答
25

有优点也有缺点。

我非常不喜欢 PEP8 兼容代码的读取方式。我不赞成那种very_long_variable_name=another_very_long_variable_namevery_long_variable_name = another_very_long_variable_name. 这不是人们阅读的方式。这是额外的认知负担,尤其是在没有语法高亮的情况下。

但是,有一个显着的好处。如果遵守间距规则,则仅使用工具搜索参数会更加有效。

于 2016-05-25T10:12:57.577 回答
16

I wouldn't use very_long_variable_name as a default argument. So consider this:

func(1, 2, axis='x', angle=90, size=450, name='foo bar')

over this:

func(1, 2, axis = 'x', angle = 90, size = 450, name = 'foo bar')

Also, it doesn't make much sense to use variables as default values. Perhaps some constant variables (which aren't really constants) and in that case I would use names that are all caps, descriptive yet short as possible. So no another_very_...

于 2012-01-13T15:43:17.323 回答
12

IMO 省略了 args 的空格,提供了 arg/值对的更清晰的视觉分组;它看起来不那么杂乱。

于 2014-03-26T21:00:51.087 回答
6

对我来说,它使代码更具可读性,因此是一个很好的约定。

我认为变量赋值和函数关键字赋值在风格上的主要区别在于=前者的一行应该只有一个,而后者的一行通常有多个=

如果没有其他考虑,我们更喜欢foo = 42foo=42因为后者不是等号通常的格式,并且因为前者在视觉上很好地将变量和值与空格分开。

但是当一行中有多个赋值时,我们更喜欢f(foo=42, bar=43, baz=44)f(foo = 42, bar = 43, baz = 44)因为前者在视觉上用空格分隔了几个赋值,而后者没有,这使得看关键字/值对的位置有点困难。

这是另一种说法:约定背后有一致性这种一致性是这样的:“最高级别的分离”通过空间在视觉上更加清晰。任何较低级别的分隔都不是(因为它会与分隔较高级别的空格混淆)。对于变量赋值,最高级别的分离是在变量和值之间。对于函数关键字分配,最高级别的分离是在各个分配本身之间。

于 2019-07-03T21:48:54.367 回答
5

我认为这有几个原因,尽管我可能只是在合理化:

  1. 它节省了空间,允许更多的函数定义和调用适合一行,并为参数名称本身节省更多空间。
  2. 通过加入每个关键字和值,您可以更轻松地通过逗号后的空格分隔不同的参数。这意味着您可以快速查看您提供了多少参数。
  3. 然后,语法与变量赋值不同,变量赋值可能具有相同的名称。
  4. 此外,语法(甚至更多)不同于等式检查a == b,后者也可以是调用中的有效表达式。
于 2014-06-08T07:17:17.507 回答
0

我个人认为,=无论编程/标记语言如何,所有赋值运算符之前和之后的单个空格都应该是标准的,因为它有助于眼睛区分不同通道的标记(即从赋值运算符标记中分离变量/参数名称标记)=,来自一个值标记/表达式值标记序列)。

将三个不同通道的三个令牌聚集成一个“参数名称分配运算符值/表达式元组”令牌既不可读也不直观。

例如,让我们考虑非定界标记:

def my_func(par1: str, par2: str):
    print('%s %s' % (par1, par2))

cond = 'conditional string'
my_func(par1='string with a lot of spaces', par2=cond if not cond == None else 'no string')

当然,传递给的值par2可能应该存储到变量中,而不是作为“三元”表达式传递......

par2 = cond if not cond == None else 'no string'
my_func(par1='string with a lot of spaces', par2=par2)

...但是无论如何我们是否应该决定使用三元表达式,我发现在赋值运算符之前和之后添加定界空格更具可读性,几乎就像字典对象(python 参数序列基本上是):

my_func(par1 = 'string with a lot of spaces', 
        par2 = cond if not cond == None else 'no string')
# OR
par2 = cond if not cond == None else 'no string'
my_func(par1 = 'string with a lot of spaces', par2 = par2)
于 2021-07-08T17:33:19.197 回答