在下图中,我对从函数temp
f
进行了查询
在本地框架f
中,当您在{{1}中说temp
时,6
是指向类int
的对象return temp
的引用变量引用变量f
是output
框架的一部分,它将指向temp指向的同一个对象checkPassingMech
。
我的问题:
Q1)我的理解是否正确?
Q2)如果Q1为是,那么这个图表给出的错觉是6
不是引用类型并且在框中显示其值而不是指向6的箭头,我是否正确?
Q3)如果Q2为是,那么,我可以说temp
实际存储在堆中,6
和temp
将从帧指向此堆空间(本地堆栈) )
答案 0 :(得分:7)
>>> def f():
temp = 6
print(id(temp))
return temp
>>> output = f()
507107408
>>> id(output)
507107408
来自doc:
CPython实现细节:对于CPython,id(x)是内存 存储x的地址。
严格地说,如果值 6 ,则output
和temp
实际上指向同一个对象,该对象是int
对象,在python启动时缓存。
您可以参考identifying objects, why does the returned value from id(...) change?了解更多信息。
答案 1 :(得分:1)
是的,你的理解是正确的,除了Python的运行时只在引用中处理对象(它们都存在于堆中):Python和#39; s堆栈(作为操作数和字节码操作的结果)总是引用(到其他地方的值)。
CPython实现中的所有Python对象都在堆上。您可以在文档中详细阅读Python的内存管理工作here:
Python中的内存管理涉及包含所有内容的私有堆 Python对象和数据结构。这个私人的管理 Python内存管理器在内部确保堆。 Python 内存管理器有不同的组件处理各种 动态存储管理方面,如共享,细分, 预分配或缓存。
答案 2 :(得分:1)
"类型几乎影响对象行为的所有方面。甚至对象标识的重要性在某种意义上也受到影响:对于不可变类型,计算新值的操作实际上可以返回对具有相同类型和值的任何现有对象的引用,而对于可变对象,这是不允许的。例如,在a = 1之后; b = 1,a和b可能会或可能不会引用具有值1的同一对象,具体取决于实现,但在c = []之后; d = [],c和d保证引用两个不同的,唯一的,新创建的空列表。 (注意c = d = []将同一个对象分配给c和d。)"
https://docs.python.org/2/reference/datamodel.html
所以你不能只用箭头指向6,因为它不能保证每次都是6的相同参考。
答案 3 :(得分:1)
1)是的。 2)是的。确实如此,temp不是引用类型,因为它不是指任何其他变量。 3)是的,值6存储在堆中(在这种情况下),无论输入如何,temp都指向6,输出等于temp,使其等于6。
您可以在此链接中获得有关引用类型的良好定义: http://msdn.microsoft.com/en-us/library/490f96s2.aspx