Python函数如何返回对象?
在下面的图中,我有一个名为 temp
的查询,它是从函数 f
返回的。
在函数 f
的局部环境中,temp
是一个引用变量,它指向一个类为 int
的对象 6
。当你在 f
中说 return temp
时,另一个引用变量 output
,它是 checkPassingMech
环境的一部分,也会指向同一个对象 6
,也就是 temp
指向的那个。
我的问题是:
Q1) 我的理解正确吗?
Q2) 如果 Q1 是对的,那么这个图给人的感觉是 temp
不是引用类型,而是把它的值放在一个框里,而不是用箭头指向 6
,我这样理解对吗?
Q3) 如果 Q2 是对的,那么我可以说 6
实际上是存储在堆内存中,而 temp
和 output
会从局部栈指向这个堆空间吗?
4 个回答
类型会影响对象的几乎所有行为。甚至对象的身份在某种程度上也会受到影响:对于不可变类型来说,计算新值的操作可能会返回一个指向任何具有相同类型和相同值的现有对象的引用,而对于可变对象,这种情况是不允许的。举个例子,假设你写了 a = 1; b = 1,这时 a 和 b 可能指向同一个值为 1 的对象,也可能不是,这取决于具体的实现。但是如果你写 c = []; d = [],那么 c 和 d 一定会指向两个不同的、唯一的新创建的空列表。(注意,c = d = [] 这行代码会让 c 和 d 指向同一个对象。)
所以你不能简单地在数字 6 上画个箭头,因为每次指向 6 的引用不一定是同一个。
1) 是的。
2) 是的,没错,temp 不是引用类型,因为它并没有指向其他的变量。
3) 是的,在这个情况下,数字六是存储在堆内存里的,而 temp 会指向数字六,无论输入是什么,输出等于 temp,所以它的值就是 6。
你可以在这个链接中找到关于引用类型的详细定义:
http://msdn.microsoft.com/en-us/library/490f96s2.aspx
是的,你的理解是对的。Python的运行时只处理指向对象的引用(这些对象都存放在堆中):在Python的栈中(作为字节码操作的操作数和结果),总是存放着对其他地方的值的引用。
在CPython的实现中,所有的Python对象都放在堆里。你可以在文档中详细了解Python的内存管理是如何工作的,这里有相关信息:
Python的内存管理涉及一个私有的堆,里面包含了所有的Python对象和数据结构。这个私有堆的管理是由Python的内存管理器内部确保的。Python的内存管理器有不同的组件,负责处理各种动态存储管理的方面,比如共享、分段、预分配或缓存。
>>> def f():
temp = 6
print(id(temp))
return temp
>>> output = f()
507107408
>>> id(output)
507107408
来自 文档:
CPython 的实现细节:在 CPython 中,id(x) 是存储 x 的内存地址。
严格来说,如果值是 6,那么 output
和 temp
实际上指向的是同一个对象,这个对象是一个在 Python 启动时就被缓存的 int
对象。
你可以参考 识别对象,为什么 id(...) 返回的值会变化? 获取更多信息。