Python中的多个赋值和求值顺序

raf*_*uru 47 python assignment-operator

以下Python表达式之间有什么区别:

# First:

x,y = y,x+y

# Second:

x = y
y = x+y
Run Code Online (Sandbox Code Playgroud)

首先给出与第二个不同的结果.

例如,

第一:

>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3
Run Code Online (Sandbox Code Playgroud)

第二:

>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4
Run Code Online (Sandbox Code Playgroud)

y第一个中是3,在第二个中是4

Fre*_*Foo 74

在赋值语句中,在进行变量的实际设置之前,始终会对右侧进行完全评估.所以,

x, y = y, x + y
Run Code Online (Sandbox Code Playgroud)

评估板y(我们称之为的结果ham),评估x + y(调用spam),然后设置xhamyspam.就是这样的

ham = y
spam = x + y
x = ham
y = spam
Run Code Online (Sandbox Code Playgroud)

相比之下,

x = y
y = x + y
Run Code Online (Sandbox Code Playgroud)

设置xy,然后设置yx(== y加)y,所以它相当于

x = y
y = y + y
Run Code Online (Sandbox Code Playgroud)


unu*_*tbu 13

它在题为"评估顺序"的部分的文档中进行了解释:

...在评估任务时,右侧在左侧之前进行评估.


Abh*_*jit 6

第一个表达:

  1. 创建一个带值的临时元组 y,x+y
  2. 分配给另一个临时元组
  3. 将元组提取到变量xy

第二个语句实际上是两个表达式,没有元组的用法。

令人惊讶的是,第一个表达式实际上是:

temp=x
x=y
y=temp+y
Run Code Online (Sandbox Code Playgroud)

您可以在“括号形式”中了解有关逗号用法的更多信息。


Cor*_*uzu 5

关于左侧的观察也是如此:分配的顺序保证是它们出现的顺序,换句话说:

a, b = c, d
Run Code Online (Sandbox Code Playgroud)

在功能上等价于精确(除了 t 创建):

t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment
Run Code Online (Sandbox Code Playgroud)

这在对象属性分配等情况下很重要,例如:

class dummy:
    def __init__(self): self.x = 0

a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"

a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
Run Code Online (Sandbox Code Playgroud)

这也意味着您可以使用单行代码执行对象创建和访问等操作,例如:

class dummy:
    def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5
Run Code Online (Sandbox Code Playgroud)