查询在python中返回本地范围的对象

时间:2015-02-02 03:53:46

标签: python

下面是返回函数function中定义的f类型对象的程序,其堆栈框架(f1)在程序退出之前仍处于活动状态。

enter image description here


下面是返回值为1024的int类型对象的程序,但是在返回int类型对象后堆栈框架不存在?

enter image description here


根据上面的两个图,当你返回int类型对象时,为什么返回类型机制(帧不存活)的区别。

返回function类型对象时,堆栈帧是否处于活动状态的想法是什么?

1 个答案:

答案 0 :(得分:4)

除非明确要求,否则Python永远不会复制(例如,切片列表确实要求Python复制列表中的那部分)。

“add_three是否引用n指向的同一个int对象?” - 是的,只有对int的引用被传递并保持在帧中。在这种情况下,这适用于n的任何值。

任何Python实现都允许保留不可变对象行int的单个副本或多个副本 - 这对于该实现最方便,因为语义不会受到影响。

因此,在给定的实现中,每次提及文字3都会引用相同的int对象,但文字333的提及不需要。 E.g:

2>>> a=333; b=333; print(id(a), id(b))
(4298804944, 4298804944)
2>>> a=333
2>>> b=333
2>>> print(id(a), id(b))
(4298753600, 4298753336)

两种情况的语义完全相同;在第一种情况下,编译器(一次在整个行上本质上调用)发现它很方便实例化并使用一个int333,在第二种情况下,它更喜欢制作和使用两个这样的实例 - 考虑到int的不变性,要么完全没问题(对于其他数字类型,字符串,元组,冻结集合也是如此 - 但对于可变类型则不然。)

请注意,当Python规范引用“相同语义”时,它明确包含内省,这可能能够查明语义等效状态之间的实现差异。

id(通常返回对象的内存地址,在当前流行的Python实现中,但无论如何,只要对象存在,每个对象的唯一ID,根据语言规范)是内省的,如因此是is运算符。因此,如果您希望使用它来理解某个实现可能执行的某些优化,那么您可以这样做。

关于你的其他问题:“我的理解是否正确?” - 不。 “为什么会出现这种差异” - def构建一个可变的函数对象,因此即使具有相同函数定义的任何def也必须返回一个新对象,就像例如[]构建一个列表一样object,mutable,所以任何[]都必须返回一个新对象。 3构建一个int对象,该对象是不可变的,因此允许任何3(根据语言规则)返回相同或新对象。

在编辑中又添加了一个问题:“当返回函数类型对象时,堆栈帧的存在是什么想法?”

答案:每个物体都可以存活,只要它可以到达。只要返回内部(嵌套)函数,外部函数的框架就会保持活动状态,如果它们引用外部框架中的名称。

(任何Python实现都没有拥有来垃圾收集不再需要活动的对象 - 它可能会延迟垃圾收集,只要它喜欢,或者可以执行它立刻 - 实施细节! - )。