为什么 Python 赋值不返回值?

新手上路,请多包涵

为什么 Python 赋值是语句而不是表达式?如果它是一个返回赋值右侧值的表达式,那么在某些情况下它会允许更少冗长的代码。有没有我看不到的问题?

例如:

 # lst is some sequence
# X is come class
x = X()
lst.append(x)

可以改写为:

 lst.append(x = X())

好吧,准确地说,上面的方法不起作用,因为 x 将被视为关键字参数。但是另一对括号(或关键字参数的另一个符号)可以解决这个问题。

原文由 max 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 766
2 个回答

许多人认为将赋值作为表达式,尤其是在像 Python 这样的语言中,在条件中允许 任何 值(而不仅仅是某些布尔类型的值)是容易出错的。大概 Guido 是那些有这种感觉的人之一。经典错误是:

 if x = y: # oops! meant to say ==

这种情况在 Python 中也比在像 C 这样的语言中复杂一点,因为在 Python 中,对变量的第一个赋值也是它的声明。例如:

 def f():
    print x

def g():
    x = h()
    print x

在这两个函数中,“ print x ”行做了不同的事情:一个引用全局变量 x ,另一个引用局部变量 x . xg 是本地的,因为分配。如果可以将赋值埋在一些更大的表达式/语句中,这可能会更加混乱(比现在更混乱)。

原文由 Laurence Gonsalves 发布,翻译遵循 CC BY-SA 2.5 许可协议

自 Python 3.8(2019 年 10 月发布)以来支持赋值(子)表达式 (x := y) ,因此您现在确实可以将示例重写为 lst.append(x := X())

该提案 PEP 572 于 2018 年 7 月被 Guido 正式接受。还有更早的赋值表达式提案,例如撤回的 PEP 379

回想一下,直到版本 3, print 还是一个语句而不是表达式。

声明 x = y = z 将相同的值分配给多个目标(或者更确切地说,多个 _目标列表_,因为也允许解包)已经被支持(例如,从版本 1 开始)但是作为特殊 语法 而不是实现通过链接连续的赋值子表达式。 Indeed, the order in which the individual assignments are performed is reversed: nested (x := (y := z)) must assign to y before x , whereas x = y = zx y (如果您设置/分配给已重载以产生一些副作用的类的下标或属性,这可能是相关的)。

原文由 benjimin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题