简体   繁体   English

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

[英]Python print function does not return the updated variable

I am learning Python and something related to print confused me. 我正在学习Python,而与print有关的东西使我感到困惑。 Not sure if someone asked the same question already: 不知道是否有人已经问过相同的问题:

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

I understand that output 1 is the side effect of Python's print function. 我知道输出1是Python print功能的副作用。 But why doesn't it print 3 ? 但是为什么不打印3呢? I was expecting 3 because x is updated in the second line? 我期待3因为x在第二行中更新了? I was thinking it is equivalent to (apparently, wrong): 我以为这等效于(显然是错误的):

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

I would like to understand the logic behind this print function. 我想了解此print功能背后的逻辑。 Why doesn't it print the updated x value? 为什么不打印更新的x值?

I am new to the programming world, so any insight is highly appreciated! 我是编程界的新手,因此非常感谢您提供任何见解!

Everything on the right-hand side is evaluated first. 首先评估右侧的所有内容。 You can use the python byte-code dissasembler to see what is happening: 您可以使用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
>>>

Note, x + 2 and print(x) are evaluated first . 注意, x + 2print(x) 首先被评估。 The BINARY_ADD and CALL_FUNCTION occur before the two STORE_NAME s. BINARY_ADD和CALL_FUNCTION出现在两个STORE_NAME之前。

Note, you can think of this as the equivalent of building a tuple first, 请注意,您可以将其视为先构建元组,

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

and then simply: 然后简单地:

x, y = temp

However, note, according to the dissasembler, no actual intermediate tuple is created. 但是,请注意,根据反汇编程序,不会创建实际的中间元组。 The call stack is used to store the intermediate values. 调用堆栈用于存储中间值。 This is a compiler optimization. 这是编译器优化。 However, the optimization does not work for tuples greater than length 3, so using 4, you'll see an intermediate tuple is create: 但是,该优化不适用于长度大于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
>>>

Note the BUILD_TUPLE and UNPACK_SEQUENCE , which is the general way that unpacking works in Python. 注意BUILD_TUPLEUNPACK_SEQUENCE ,这是在Python中解UNPACK_SEQUENCE的一般方法。 It's just the compiler optimizes the common cases of two-or-three with the ROT_TWO and ROT_THREE op codes. 只是编译器使用ROT_TWO和ROT_THREE操作码优化了二到三的常见情况。

Note, since the right-hand side is evaluate first, this allows for the Python swap idiom to work! 请注意,由于右侧是第一个求值对象,因此可以使用Python交换习惯!

x, y = y, x

If this were equivalent to: 如果这等效于:

x = y
y = x

You would lose the value for x instead of swapping! 您将失去x的值,而不是交换!

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

print(x) outputs the value stored in x assigned by you print(x)输出由您分配的x中存储的值

for printing 3 you need to print(y) 打印3您需要打印(y)

as y stores the value of x+2 因为y存储x + 2的值

Because python processes line by line (meaning after the whole line, process it), so x haven't updated yet, so that's why it's not working as expected, but if you do ; 因为python逐行处理(意味着在整行之后进行处理),所以x尚未更新,所以这就是为什么它无法按预期运行的原因,但是如果您这样做,则不会; (semicolon) it will work, because semicolon ; (分号)将起作用,因为分号; is basically a separator of lines too, so basically everything after ; 基本上也是行的分隔符,因此基本上所有后面的内容; is taken as a new line, demo: 用作新行,演示:

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

Issue is that y is gonna be 0: 问题是y将为0:

>>> y
0
>>> 

Because i do so, you have to have a value, 因为我这样做,所以你必须有一个价值,

But if you care, delete it: 但是,如果您愿意,请删除它:

>>> 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
>>> 

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM