Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python打印函数不返回更新的变量_Python_Printing_Assign - Fatal编程技术网

Python打印函数不返回更新的变量

Python打印函数不返回更新的变量,python,printing,assign,Python,Printing,Assign,我正在学习Python和一些与print相关的东西,这让我很困惑。不确定是否有人已经问过同样的问题: >>> x = 1 >>> x, y = x + 2, print(x) 1 我知道输出1是Python的print函数的副作用。但是为什么它不打印3?我期待3,因为x在第二行被更新了?我认为这相当于(显然是错误的): 我想了解这个print功能背后的逻辑。为什么它不打印更新后的x值 我是编程界的新手,因此任何见解都是高度赞赏的 首先评估右侧的所有内容。您可

我正在学习Python和一些与
print
相关的东西,这让我很困惑。不确定是否有人已经问过同样的问题:

>>> x = 1
>>> x, y = x + 2, print(x)
1
我知道输出
1
是Python的
print
函数的副作用。但是为什么它不打印
3
?我期待
3
,因为
x
在第二行被更新了?我认为这相当于(显然是错误的):

我想了解这个
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)
首先计算。二进制添加和调用函数出现在两个
STORE\u NAME
s之前

注意,您可以将其视为先构建一个元组

temp = (x + 2, print(x))
然后简单地说:

x, y = temp
但是,请注意,根据disassembler,没有创建实际的中间元组。调用堆栈用于存储中间值。这是一个编译器优化。但是,优化不适用于长度大于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\u TUPLE
UNPACK\u SEQUENCE
,这是Python中解包工作的一般方式。只是编译器用ROT_2和ROT_3操作码优化了两个或三个常见情况

注意,由于右侧是evaluate first,这就允许Python交换习惯用法工作

x, y = y, x
如果这相当于:

x = y
y = x
您将丢失x的值,而不是交换

>>> x = 1
>>> x, y = x + 2, print(x)
1
打印(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
>>> 
>x=1
>>>x,y=x+2,0;打印(x)
3.
>>>德利
>>>y
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
Y
名称错误:未定义名称“y”
>>> 

直到右侧的所有内容都处理完毕,作业左侧的值才会更新。这就是为什么当您尝试在右侧打印时X还不是3。

哇,您的解释有深度。我从未听说过这个字节码分解器,但它是理解Python底层活动的一个非常有用的工具。非常感谢
>>> 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
>>>