Python3多重赋值和内存地址
发布时间:2020-12-20 13:15:13 所属栏目:Python 来源:网络整理
导读:参见英文答案 ‘is’ operator behaves unexpectedly with non-cached integers????????????????????????????????????2个 在阅读了与我的问题非常相似的 this和 this之后,我仍然无法理解以下行为: a = 257b = 257print(a is b) #Falsea,b = 257,257print(a
参见英文答案 >
‘is’ operator behaves unexpectedly with non-cached integers????????????????????????????????????2个
在阅读了与我的问题非常相似的 this和 this之后,我仍然无法理解以下行为: a = 257 b = 257 print(a is b) #False a,b = 257,257 print(a is b) #True 当打印id(a)和id(b)时,我可以看到在单独的行中赋值的变量具有不同的id,而对于多个赋值,两个值具有相同的id: a = 257 b = 257 print(id(a)) #139828809414512 print(id(b)) #139828809414224 a,257 print(id(a)) #139828809414416 print(id(b)) #139828809414416 但是,通过说多个相同值的赋值总是创建指向同一个id的指针,从而解释这种行为是不可能的: a,b = -1000,-1000 print(id(a)) #139828809414448 print(id(b)) #139828809414288 是否有一个明确的规则,它解释了变量何时获得相同的ID而不是? 编辑 相关信息:此问题中的代码以交互模式运行(ipython3) 解决方法
这是由于字节码编译器中的常量折叠优化.当字节码编译器编译一批语句时,它会跟踪
uses a dict跟踪它看到的常量.此dict自动合并任何等效常量.
这是负责记录和编号常量的例程(以及一些相关的职责): static int compiler_add_o(struct compiler *c,PyObject *dict,PyObject *o) { PyObject *t,*v; Py_ssize_t arg; t = _PyCode_ConstantKey(o); if (t == NULL) return -1; v = PyDict_GetItem(dict,t); if (!v) { arg = PyDict_Size(dict); v = PyInt_FromLong(arg); if (!v) { Py_DECREF(t); return -1; } if (PyDict_SetItem(dict,t,v) < 0) { Py_DECREF(t); Py_DECREF(v); return -1; } Py_DECREF(v); } else arg = PyInt_AsLong(v); Py_DECREF(t); return arg; } 您可以看到它只添加了一个新条目,并且如果找不到已存在的等效常量,则分配一个新数字. (_PyCode_ConstantKey位确保0.0,-0.0和0之类的东西被认为是不等价的.) 在交互模式下,每次解释器必须实际运行命令时批处理结束,因此在命令之间不会发生常量折叠: >>> a = 1000 >>> b = 1000 >>> a is b False >>> a = 1000; b = 1000 # 1 batch >>> a is b True 在脚本中,所有顶级语句都是一个批处理,因此more constant folding happens: a = 257 b = 257 print a is b 在脚本中,这将打印True. 函数的代码使其常量与函数外部的代码分开跟踪,这限制了常量折叠: a = 257 def f(): b = 257 print a is b f() Even in a script,这打印错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |