Python打印功能不返回更新的变量

时间:2018-12-11 03:45:22

标签: python printing assign

我正在学习Python,而与print相关的东西使我感到困惑。不确定是否有人已经问过相同的问题:

>>> x = 1
>>> x, y = x + 2, print(x)
1

我知道输出1是Python print函数的副作用。但是为什么不打印3?我期待3是因为x在第二行中已更新?我以为这等效于(显然是错误的):

>>> x = 1
>>> x = x + 2
>>> x
3
>>> y = print(x)
3

我想了解此print函数背后的逻辑。为什么不打印更新后的x值?

我是编程界的新手,所以对任何见解都表示赞赏!

4 个答案:

答案 0 :(得分:3)

首先评估右侧的所有内容。您可以使用python字节码反汇编器查看正在发生的事情:

>>> import dis
>>> dis.dis('x, y = x + 2, print(x)')
  1           0 LOAD_NAME                0 (x)
              2 LOAD_CONST               0 (2)
              4 BINARY_ADD
              6 LOAD_NAME                1 (print)
              8 LOAD_NAME                0 (x)
             10 CALL_FUNCTION            1
             12 ROT_TWO
             14 STORE_NAME               0 (x)
             16 STORE_NAME               2 (y)
             18 LOAD_CONST               1 (None)
             20 RETURN_VALUE
>>>

请注意,x + 2print(x)的评估是 first 。 BINARY_ADD和CALL_FUNCTION发生在两个STORE_NAME之前。

请注意,您可以认为这等同于首先构建一个元组,

temp = (x + 2, print(x))

然后简单地:

x, y = temp

但是,请注意,根据反汇编程序,没有创建任何实际的中间元组。调用堆栈用于存储中间值。这是编译器优化。但是,该优化不适用于长度大于3的元组,因此使用4时,您会看到创建了一个中间元组:

>>> dis.dis('foo, bar, baz, bang  = bang, baz, bar, foo')
  1           0 LOAD_NAME                0 (bang)
              2 LOAD_NAME                1 (baz)
              4 LOAD_NAME                2 (bar)
              6 LOAD_NAME                3 (foo)
              8 BUILD_TUPLE              4
             10 UNPACK_SEQUENCE          4
             12 STORE_NAME               3 (foo)
             14 STORE_NAME               2 (bar)
             16 STORE_NAME               1 (baz)
             18 STORE_NAME               0 (bang)
             20 LOAD_CONST               0 (None)
             22 RETURN_VALUE
>>>

请注意BUILD_TUPLEUNPACK_SEQUENCE,这是在Python中解压缩的一般方法。只是编译器使用ROT_TWO和ROT_THREE操作码优化了二到三的常见情况。

请注意,由于首先要评估右侧,因此可以使用Python交换习惯用法!

x, y = y, x

如果这等同于:

x = y
y = x

您将失去x的值而不是交换!

答案 1 :(得分:0)

>>> x = 1
>>> x, y = x + 2, print(x)
1

print(x) 输出存储在您分配的x中的值

要打印3,您需要 打印(y)

作为y存储x + 2的值

答案 2 :(得分:0)

因为python逐行处理(意味着在整行之后对其进行处理),所以x尚未更新,因此这无法按预期运行,但是如果您进行; (分号)就可以了,因为分号;基本上也是行的分隔符,因此;之后的所有内容基本上都被当作新行,演示:

>>> x=1
>>> x, y = x + 2,0; print(x)
3
>>> 

问题是y将为0:

>>> y
0
>>> 

因为我这样做,所以您必须有一个值

但是,如果需要的话,将其删除:

>>> x=1
>>> x, y = x + 2,0; print(x)
3
>>> del y
>>> y
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    y
NameError: name 'y' is not defined
>>> 

答案 3 :(得分:0)

在处理完右侧的所有内容之前,赋值左侧的值不会更新。这就是为什么当您尝试在右侧打印时X尚未为3的原因。