Python3多重赋值与内存地址

标签 python python-3.x multiple-assignment

<分区>

看完thisthis ,这与我的问题非常相似,但我仍然无法理解以下行为:

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, b = 257, 257
print(id(a)) #139828809414416
print(id(b)) #139828809414416

但是不可能通过说相同值的多次赋值总是创建指向相同 id 的指针来解释这种行为,因为:

a, b = -1000, -1000  
print(id(a)) #139828809414448
print(id(b)) #139828809414288

是否有明确的规则来解释变量何时获得相同的 id 以及何时不同?

编辑

相关信息:本题代码以交互方式运行(ipython3)

最佳答案

这是因为 python 解释器在 UNPACK_SEQUENCE 时进行了优化,在加载常量值的过程中。当 python 在解包过程中遇到可迭代对象时,它不会多次加载重复的对象,而是只保留第一个对象并将所有重复的变量名分配给一个指针(在 CPython 实现中)。因此,您所有的变量都将成为对一个对象的相同引用。在 Python 级别,您可以将此行为视为使用字典作为不保留重复键的 namespace 。

换句话说,您的解包相当于以下命令:

a = b = 257

关于负数,在 python 2.X 中它没有任何区别,但在 python 3.X 中似乎对于小于 -5 的数字,python 将在解包期间创建新对象:

>>> a, b = -6, -6
>>> a is b
False
>>> a, b = -5, -5
>>> 
>>> a is b
True

关于Python3多重赋值与内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35275026/

相关文章:

python - Ruby 正则表达式与 Python 正则表达式

python - 添加到整数列表的列表

python - 如何可视化 BaseHTTPRequestHandler 的主体部分

python - 创建没有深拷贝的列表子类

python - 如何与 Telegram bot python同时工作

python - 如何在 opencv-python 中将文本打印到框架

python - 匹配器正在返回一些重复项

c - C 是否像 python 一样支持 a , b = 0, 1 类型的多重赋值?

Python3多重赋值与内存地址