Python 打印函数不return 更新的变量
Python print function does not return the updated variable
我正在学习 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
值?
我是编程界的新手,非常感谢任何见解!
首先评估右侧的所有内容。您可以使用 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 + 2
和 print(x)
被评估为 首先 。 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_TUPLE
和 UNPACK_SEQUENCE
,这是在 Python 中解包的一般方式。这只是编译器使用 ROT_TWO 和 ROT_THREE 操作码优化了二或三的常见情况。
请注意,由于右侧首先求值,因此 Python 交换习语可以使用!
x, y = y, x
如果这等同于:
x = y
y = x
你会失去 x 的价值而不是交换!
>>> x = 1
>>> x, y = x + 2, print(x)
1
print(x)
输出存储在你指定的 x 中的值
要打印 3,您需要
打印(y)
因为 y 存储了 x+2 的值
因为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
>>>
直到右侧的所有内容都完成后,赋值左侧的值才会更新processing.That这就是当您尝试在右侧打印时 X 还不是 3 的原因右手边。
我正在学习 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
值?
我是编程界的新手,非常感谢任何见解!
首先评估右侧的所有内容。您可以使用 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 + 2
和 print(x)
被评估为 首先 。 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_TUPLE
和 UNPACK_SEQUENCE
,这是在 Python 中解包的一般方式。这只是编译器使用 ROT_TWO 和 ROT_THREE 操作码优化了二或三的常见情况。
请注意,由于右侧首先求值,因此 Python 交换习语可以使用!
x, y = y, x
如果这等同于:
x = y
y = x
你会失去 x 的价值而不是交换!
>>> x = 1
>>> x, y = x + 2, print(x)
1
print(x)
输出存储在你指定的 x 中的值
要打印 3,您需要 打印(y)
因为 y 存储了 x+2 的值
因为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
>>>
直到右侧的所有内容都完成后,赋值左侧的值才会更新processing.That这就是当您尝试在右侧打印时 X 还不是 3 的原因右手边。