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

为什么 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语句的同一行上使用 {,而不是 是否,我是否应该使用它。

50347 次浏览

我猜想这是因为关键字参数与变量赋值本质上是不同的。

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

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

正如您所看到的,将一个变量赋给一个名称完全相同的关键字参数是完全有意义的,因此可以提高在不使用空格的情况下查看它们的可读性。更容易认识到的是,我们使用的是关键字参数,而不是赋予变量本身。

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

我不会使用 very _ long _ variable _ name 作为默认参数:

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

关于这个:

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

而且,使用变量作为默认值也没有多大意义。也许是一些常量变量(它们并不是真正的常量) ,在这种情况下,我会使用全部大写、描述性但尽可能短的名称。因此,没有其他 _ 非常 _..。

IMO 省略了 args 的空间,使得 arg/值对的视觉分组更加清晰; 看起来不那么凌乱。

我认为有几个原因,虽然我可能只是合理化:

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

有利有弊。

我非常不喜欢符合 PEP8的代码的读取方式。我不认为 very_long_variable_name=another_very_long_variable_name比任何时候都更具有人类可读性 very_long_variable_name = another_very_long_variable_name. 这不是人们阅读的方式,这是一种额外的认知负担,特别是在没有语法突显的情况下。

然而,这样做有一个显著的好处。如果遵循间距规则,则只搜索 使用工具参数的效率将大大提高。

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

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

如果没有其他考虑因素,我们更倾向于使用 foo = 42而不是 foo=42,因为后者不是等号通常的格式,而且因为前者用空格很好地直观地分隔了变量和值。

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

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

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

将三个不同通道的三个标记集中到一个单独的“参数-名称-赋值-操作符-值/表达式-元组”标记中既不可读,也不直观。

例如,让我们考虑未分隔的令牌:

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')

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

par2 = cond if cond is not 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 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)