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 运行时)。
我运行下面的代码在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 运行时)。