【问题标题】:Assign within if statement Python在 if 语句 Python 中赋值
【发布时间】:2015-07-15 23:40:39
【问题描述】:

有没有比

更简单的选择
res = returns_value_or_none(arg)
if res:
    do_something_with(res)

if returns_value_or_none(arg):
    do_something_with(returns_value_or_none(arg))

将赋值和if 条件组合到一个语句中?

【问题讨论】:

  • 第一种方式很好。如果返回值可以是其他一些有效但错误的值(例如空字符串),请务必使用if res is None
  • 您真正要在这里寻找的是 C 风格的 if res=spam():if (ch=getch()) != EOF:,而 Python 没有。 Python 有充分的理由。 Swift 有不同的理由。如果您正在设计一种新语言,并且如果没有令人信服的理由,那么节省一行或 5 个字符可能是值得的,但您可能有其他令人信服的理由。

标签: python if-statement assign


【解决方案1】:

通常,你所拥有的已经是最好的选择。


你总是可以创建一个新的作用域来将值绑定到一个变量:

(lambda res: do_something_with(res) if res else None)(returns_value_or_none(arg))

但这肯定不会更易读,或者更 Pythonic。


如果你只想保存一行,你可以这样做:

res = returns_value_or_none(arg)
if res: do_something_with(res)

有时更具可读性,但通常是净损失。


解决此问题的另一种方法是将do_something_with 更改为接受None 并且什么也不做。这在 Python 中并不像在 Smalltalk 或 Swift 中那样常见,但有时它确实有它的位置。

很难理解为什么使用这样一个玩具示例,但如果您调用这些函数 70 次,则将检查放在函数内部的一个地方,而不是 70 个地方,它被调用的任何地方,是显而易见的赢。 (特别是因为您可能会将其放在 68 个位置而忘记其他 2 个。)


最后但并非最不重要的一点是,在许多情况下,正确的答案是例外。如果您通过None,您的do_something_with 可能已经加注。您当然可以将returns_value_or_none 更改为returns_value_or_raises

同样,在这个玩具示例中,它看起来更像是更多代码。但在实际代码中,将整个代码块放在try/except 中并在最后一次处理所有错误通常是有意义的。或者甚至让异常渗透到更容易处理的更高级别。

当然,这并不适用于所有情况;如果您期望None 是一个频繁且完全合理的响应,并且只想跳过一个步骤而不是中止整个操作链,那么检查或通过None 将比乱扔垃圾更有意义您的代码带有小 try 块。

【讨论】:

  • 谢谢,我想我对一些语法糖持乐观态度。允许被调用函数采用 None 的问题在于,在其他情况下,如果收到 None 或其他无效类型,我希望相同的函数引发错误。另外,在大多数情况下,它类似于if re.match(some_pattern, text): do_something_with(re.match(some_pattern, text).group(1))。如果忘记了 if 条件并且 re.match() 返回 None ,解释器会尽快通知我。
  • @Peter:通常让解释器让你知道并没有错(“你”是指代码中的 except 处理程序,还是没有考虑值的可能性的程序员)可能是None,因此没有编码)。
  • @Peter:同时,如果你只给我们看一个毫无意义的玩具例子,你只会得到“这里有六种方法可以做类似的事情;哪一种适合你的真实代码取决于那个真实的代码”;如果您向我们展示几个真实的示例,我们可以向您展示处理这些示例的惯用方式。
【解决方案2】:

对于 Python 3.8+,PEP 572 引入了赋值表达式

这允许使用符号NAME := expr 分配给表达式中的变量。它可以在 if 语句中使用,例如:

if (match := pattern.search(data)) is not None:
    # Do something with match

【讨论】:

  • 你忘了提到这个新操作员的非正式名称,“海象操作员”。
猜你喜欢
  • 2020-08-07
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2020-01-20
  • 2011-10-31
  • 2021-08-13
  • 1970-01-01
  • 2011-02-15
相关资源
最近更新 更多