python - Python打印函数不返回更新的变量
问题描述
我正在学习 Python 和一些相关的东西让我很print
困惑。不确定是否有人已经问过同样的问题:
>>> x = 1
>>> x, y = x + 2, print(x)
1
我知道输出是 Python函数1
的副作用。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 出现在两个s 之前。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
and UNPACK_SEQUENCE
,这是在 Python 中解包的一般方式。只是编译器使用 ROT_TWO 和 ROT_THREE 操作码优化了二或三的常见情况。
注意,由于右手边是先评估的,这使得 Python 交换习语可以工作!
x, y = y, x
如果这相当于:
x = y
y = x
你会失去 x 的价值而不是交换!
推荐阅读
- json - 在 JOLT concat 中苦苦挣扎
- reactjs - 打开切换后将徽章的值设置为0
- c - 无法打开printf,无法读取文件
- python - 如何覆盖用户模型的“save_model”方法ModelAdmin?
- excel - 自动大小/调整用户表单
- c - 使用WDK制作蓝牙游戏手柄的驱动
- javascript - 有没有办法使用电子反应将文件本地存储在计算机上
- php - 是否有用于在 PHP 中初始化关联数组或对象的简写表示法,例如在 ES2015 中引入 JavaScript 的那种?
- c# - 当 WebApi 在单独程序集中的内存中托管时,DI 不起作用
- unetstack - UnetStack - 物理参数