[英]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 + 2
和print(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_TUPLE
和UNPACK_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.