Python 语法:从三元表达式中的函数 return 值解压多个变量给出意外结果

Python syntax: unpacking multiple variables from function return value in ternary expression gives unexpected result

我注意到在解包三元表达式中的多个值时出现一个奇怪的问题。首先,一个 MWE 说明了语法,其目的是解压右侧的元组并将其中的列表分配给左侧的第一个名字,并将数字分配给第二个名字。

condition = False
a, b = [1, 2], 3 if not condition else None, None  # ValueError: too many values to unpack
def foo():
    return [1, 2], 3
([1, 2], 3) == foo()  # True
a, b = foo()  # works as expected: a = [1, 2] and b = 3
a, b = foo() if not condition else None, None  # now a = ([1, 2], 3) and b is None

我的问题是了解此处语法背后的基本原理。如果 condition 的计算结果为 false,为什么要对三元表达式的最后一部分 else 子句进行计算? Python 是否将第二个 None 分配给 b?这对我来说毫无意义,但我看不出还有什么其他方法 a) 没有出现 ValueError 告诉我解包根本不起作用(如果我的语法以某种方式强制 Python 将整个元组视为一个实体而不是而不是解包)和 b) 一个值仍然分配给 b。显而易见的下一个测试:

a, b = foo() if not condition else None, 'test'  # Now a = ([1, 2], 3) and b = 'test'
a, b = (lambda x: [[1, 2], 3])('blah') if not condition else None, 'test'  # Same result with a lambda function.

因此,else 子句似乎正在被评估。为什么会这样?有没有一种优雅的方式来重写它以允许我在这样一个三元表达式中调用函数,除了明显的和可以说是笨拙的

if not condition:
    a, b = foo()
else:
    a, b = None, None

这只是优先级。 Python 将其解析为:

a, b = (foo() if not condition else None), None

对于您的预期结果,您需要在 Nones 周围添加括号:

a, b = foo() if not condition else (None, None)

这里发生的是,python 将您的三元表达式作为第一个要解包的项目,, None 作为第二个。括号相同:

a, b = (foo() if not condition else None), None

这可以通过以下方式缓解:

a, b = foo() if not condition else (None, None)

哪个会给你正确的结果:

>>> a, b = foo() if not condition else (None, None)
>>> a, b
([1, 2], 3)