python 解释器和 python 程序中变量分配的差异

Difference in variable allocation in python interpreter and python program

我运行下面的代码在python解释器

Python 2.7.12 (default, Sep 20 2016, 14:42:48)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 300
>>> y = 300
>>> id(x)
140510001982256
>>> id(y)
140510001982160

然后我写了一个小程序运行它:

计划:

 x = 15000
 y = 15000

 if __name__ == "__main__":
     print (id(x))
     print (id(y))

输出:

$ python mem_test.py
140525354104776
140525354104776

这是什么原因?

id(对象)
Return 对象的“身份”。这是一个整数(或长整数),保证此对象在其生命周期内是唯一且不变的。两个生命周期不重叠的对象可能具有相同的 id() 值

CPython实现细节: 这是对象在内存中的地址。

从该描述中您可以理解 id(Object) returns 为变量提供非重叠 space 的唯一常量。

您是在熟练地使用内存中对象位置的标识。由于整数是不可变的,因此每个整数值都是一个具有唯一 ID 的不同对象。整数 1500 与 1499.If 具有不同的 id,您展开变量,值 1500 仅存储一次,其他所有内容仅指向该值,该值将引用数字 1500 的内存位置。

例如:

x = 1500
z = x
f = z
y = 1500
n = 1499

if __name__ == "__main__":
     print (id(x))
     print (id(z))
     print (id(f))
     print (id(y))
     print (id(n))
>>> 
50864556
50864556
50864556
50864556
50733712
>>> 

对象 ID 是 实现定义的 "blackbox" 值。唯一的保证是给定对象将在其整个生命周期内保持相同的 id,并且没有其他对象(在同一进程中......)在同一时间共享此 id(但 id 可以重复用于另一个对象同一个进程,第一个对象已被垃圾回收)。

请注意,出于性能原因,实现可以自由缓存不可变对象,并且 CPython 确实在某些情况下缓存了一些不可变对象 - 特别是 "small" 整数(对于 "small" 的定义已从一个版本更改为另一个版本)和可能是有效 variables/functions/classes/modules 名称的字符串,但这实际上只是一个实现细节。 FWIW,看起来有些缓存不再发生在 REPL 的顶层(如果它曾经发生在这里)——但它仍然发生在 REPL 中定义的函数中:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
pythonrc start
pythonrc done
>>> x = 300
>>> y = 300
>>> id(x)
37126296
>>> id(y)
37126248
>>> def foo():
...    x = 300; print "id(x): %s" % id(x)
...    y = 300; print "id(y): %s" % id(y)
... 
>>> foo()
id(x): 37126200
id(y): 37126200
>>> foo()
id(x): 37126200
id(y): 37126200
>>> foo()
id(x): 37126200
id(y): 37126200
>>> id(x)
37126296
>>> id(y)
37126248

长话短说:你不应该关心这个(当然,除非你正在编写自己的 python 运行时)。