a=[1234,1234] #list
a
[1234, 1234]
id(a[0])
38032480
id(a[1])
38032480
b=1234 #b is a variable of integer type
id(b)
38032384
为什么id(b)与python中的id(a [0])和id(a [1])不同?
最佳答案
当CPython REPL执行一行时,它将:
可以通过
dis
module检查编译结果:>>> dis.dis('a = [1234, 1234, 5678, 90123, 5678, 4321]')
1 0 LOAD_CONST 0 (1234)
2 LOAD_CONST 0 (1234)
4 LOAD_CONST 1 (5678)
6 LOAD_CONST 2 (90123)
8 LOAD_CONST 1 (5678)
10 LOAD_CONST 3 (4321)
12 BUILD_LIST 6
14 STORE_NAME 0 (a)
16 LOAD_CONST 4 (None)
18 RETURN_VALUE
请注意,所有1234都加载了“
LOAD_CONST 0
”,所有5678都加载了“LOAD_CONST 1
”。这些引用与代码对象关联的常量表。这里的表是(1234, 5678, 90123, 4321, None)
。编译器知道代码对象中所有1234的副本都是相同的,因此将只为所有对象分配一个对象。
因此,正如OP所观察到的,
a[0]
和a[1]
确实确实引用了同一对象:该行代码对象的常量表中的相同常量。当您执行
b = 1234
时,它将再次编译并执行,与上一行无关,因此将分配一个不同的对象。 (您可以阅读http://akaptur.com/blog/categories/python-internals/以获得有关如何解释代码对象的简要介绍)
在REPL之外,当您执行
*.py
文件时,每个函数都被编译成单独的代码对象,因此在运行时:a = [1234, 1234]
b = 1234
print(id(a[0]), id(a[1]))
print(id(b))
a = (lambda: [1234, 1234])()
b = (lambda: 1234)()
print(id(a[0]), id(a[1]))
print(id(b))
我们可能会看到类似以下内容的内容:
4415536880 4415536880
4415536880
4415536912 4415536912
4415537104
a[0]
和a[1]
具有第一个lambda的地址4415536912。 b
具有第二个lambda的地址4415537104。 另请注意,此结果仅对CPython有效。其他实现在分配常量方面有不同的策略。例如,在PyPy中运行上面的代码将给出:
19745 19745
19745
19745 19745
19745
关于Python,变量存储在内存中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43294941/