PEP 8,为什么关键字参数中的'='周围没有空格或默认参数值?

sou*_*eck 95 python coding-style pep8

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

这与=Python代码中每隔一次出现的推荐空格不一致吗?

怎么:

func(1, 2, very_long_variable_name=another_very_long_variable_name)
Run Code Online (Sandbox Code Playgroud)

优于:

func(1, 2, very_long_variable_name = another_very_long_variable_name)
Run Code Online (Sandbox Code Playgroud)

任何由Python的BDFL讨论/解释的链接都将受到赞赏.

记住,这个问题更多的是关于kwargs而不是默认值,我只是使用了PEP 8中的措辞.

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

for*_*ran 64

我想这是因为关键字参数本质上不同于变量赋值.

例如,有很多这样的代码:

kw1 = some_value
kw2 = some_value
kw3 = some_value
some_func(
    1,
    2,
    kw1=kw1,
    kw2=kw2,
    kw3=kw3)
Run Code Online (Sandbox Code Playgroud)

如您所见,将变量分配给名称完全相同的关键字参数是完全有意义的,因此它提高了可见性,无需空格即可查看它们.我们更容易认识到我们正在使用关键字参数而不是为自己分配变量.

此外,参数往往在同一行,而赋值通常是各自的一行,因此节省空间可能是一个重要的问题.

  • 我会说它不是比`kw1 = kw1,kw2 = kw2`;更可读,但也许这就是Guido和Barry的想法. (5认同)
  • 可能是这种情况,但在这种精心设计的语言的代码风格建议中引入这种IMO图标一致性似乎仍然很奇怪,只能保存2个字符.就像java代码样式所说的那样,在`if`之后将`{`放在一个新行上(保存相同数量的字符)而不是在类定义中.关键字参数也与默认值不同,但仍使用相同的样式建议. (4认同)
  • 关键字参数与变量赋值根本不同的事实不是具有不同约定IMO的有效参数,因为差异已经从上下文中清楚了.前者发生_within_函数调用,而后者需要独立于当前缩进级别.IMO,对于长度超过5-6个字符的变量名称(即大多数的现实生活),具有空格的变体更具可读性. (4认同)
  • 正如我所说,它们是不同的东西.以不同的方式编写它们是有意义的. (3认同)

rpl*_*lnt 12

我不会使用very_long_variable_name作为默认参数.所以考虑一下:

func(1, 2, axis='x', angle=90, size=450, name='foo bar')
Run Code Online (Sandbox Code Playgroud)

对此:

func(1, 2, axis = 'x', angle = 90, size = 450, name = 'foo bar')
Run Code Online (Sandbox Code Playgroud)

此外,将变量用作默认值也没有多大意义.也许是一些常量变量(它们不是真正的常量),在这种情况下,我会使用全部大写的名称,描述性尽可能短.所以没有其他_每个_...

  • 你(基本上)说:要使无空间规则合理,写出非常短的变量名.但如果一个人拥有长期变量名称,那么无空间规则就会造成一个混乱的环境."它不是一个任务,所以它们是不同的东西"的论点并没有为我减少它,因为我更关心易读性而不是语义,因为如果它不是'赋值的'默认值',那么什么是它? (3认同)
  • @PatrickT“这不是一项作业,所以它们是不同的东西”这一论点无法解释_为什么它是_(一个哲学概念);它只是解释_为什么它可以_(一个句法概念)。 (2认同)

小智 8

IMO省去了args的空间,为arg/value对提供了更清晰的视觉分组; 它看起来不那么杂乱.


小智 8

有利有弊.

我非常不喜欢符合PEP8的代码.我不会very_long_variable_name=another_very_long_variable_name接受比人类更容易阅读 的论点very_long_variable_name = another_very_long_variable_name.这不是人们阅读的方式.这是一种额外的认知负荷,特别是在没有语法突出显示的情况下.

然而,有一个重要的好处.如果遵守间距规则,则仅使用工具搜索参数更有效.

  • @NoName 如果您在分配周围放置空格并且默认/关键字周围没有空格,那么搜索**排除另一个**会更容易(带或不带空格搜索)。 (3认同)

Noo*_*ath 7

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

将三个不同通道的三个标记聚集成单个“参数-名称-赋值-运算符-值/表达式-元组”标记既不可读也不直观。

例如,让我们考虑非分隔标记:

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 cond is not None else 'no string')
Run Code Online (Sandbox Code Playgroud)

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

par2 = cond if cond is not None else 'no string'
my_func(par1='string with a lot of spaces', 
        par2=par2)
Run Code Online (Sandbox Code Playgroud)

...但是我们应该决定使用三元表达式吗?我发现在赋值运算符之前和之后添加分隔空格会更具可读性,几乎就像一个字典对象(Python 参数序列基本上就是这样):

my_func(par1 = 'string with a lot of spaces', 
        par2 = cond if cond is not None else 'no string')
# OR
par2 = cond if cond is not None else 'no string'
my_func(par1 = 'string with a lot of spaces', 
        par2 = par2)
Run Code Online (Sandbox Code Playgroud)


otu*_*tus 5

我认为造成这种情况的原因有几个,尽管我可能只是在合理化:

  1. 它节省了空间,允许更多的函数定义和调用放在一行中,并为参数名称本身节省了更多空间。
  2. 通过连接每个关键字和值,您可以更轻松地用逗号后面的空格分隔不同的参数。这意味着您可以快速查看您提供了多少参数。
  3. 语法与变量赋值不同,变量赋值可能具有相同的名称。
  4. 此外,语法(甚至更)与相等检查不同a == b,相等检查也可以是调用内的有效表达式。


Den*_*loe 5

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

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

如果没有其他方面的考虑,我们宁愿foo = 42foo=42,因为后者并不怎么等号通常格式化,因为前者在视觉上很好地分隔使用空格变量和值。

但是,当有一行中的多个任务,我们更f(foo=42, bar=43, baz=44)f(foo = 42, bar = 43, baz = 44),因为前者在视觉上与分离空白的几个任务,而后者则没有,使得它有点难以看到的关键字/值对。

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