Python print 函数不返回更新后的变量

标签 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 值?

我是编程世界的新手,因此非常感谢任何见解!

最佳答案

首先评估右侧的所有内容。您可以使用 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) 首先计算。 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 的值!

关于Python print 函数不返回更新后的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53717080/

相关文章:

java - 未找到打印服务错误消息

python - 使用 Mega 模块命令的预期字符串或缓冲区

java - 打印居中对齐的二维数组

javascript - PDF.js 如何打印多页 pdf?

python - 如何生成许多列表并为其赋值

Java:从数组实例化变量

python - 如何在 django 博客文章中添加图像

python - 从 Python 调用 CAPL 函数

python - 在 Python 上读取文件时,我收到了 UnicodeDecodeError。我能做些什么来解决这个问题?

case - VHDL 中 CASE 语句中的多项赋值