我正在处理的原始问题概述为here。我想问一个与原始问题相关的其他问题(关于Python引用计数)。
假设我有以下脚本:
from bitarray import bitarray
from array import array
list1=[bitarray('00011'), bitarray('00010'), bitarray('11011')]
list2=[array('i',[0,0,0,0]),array('i',[1,1,1,1]),array('i',[2,2,2,2])]
def calculate(l1,l2):
result1=l1[0]&l1[1]&l1[2]
result2=l2[0][0]+l2[1][1]+l2[2][2]
return result1, result2
print calculate(list1,list2)
当我致电list1
时,list2
,calculate(list1,list2)
或任何一个列表中的任何对象的引用计数是否会在某些时候发生 ?
只是为了澄清:我并不是说在调用calculate(list1,list2)
之前和之后引用计数是否相同。我的意思是如果引用计数在执行calculate(list1,list2)
期间的任何时候发生变化。
答案 0 :(得分:3)
list1
和list2
的引用计数不会更改,它们只是变量,因此是locals()
命名空间中的字符串键。
这两个变量指向的Python列表对象,但是,它们的引用计数在传递给函数时会发生变化。在调用函数期间,两个 new 变量引用那些增加计数的列表(l1
和l2
),当函数返回时,这些变量被清理并且ref伯爵再次下降。
在calculate()
函数中,您正在访问这两个列表(l1[0]
等)的项目。项目访问可以使用对象的__getitem__
方法;方法在访问时即时创建,并保存对实例和基础函数的引用。对于列表是列表对象的另一个引用,另一个临时引用计数增加。一旦调用了函数并返回了它的值,该方法将再次被丢弃(没有任何内容引用它),并且列表的引用计数再次下降。
正如delnan在评论中正确指出的那样,对于列表订阅, python解释器在处理堆栈上的字节码和值时,一直在增加和减少引用计数 。仔细查看Python bytecode evaluation loop并计算BINARY_SUBSCR
操作码优化访问(假设索引是整数),并且在该特定情况下没有创建的方法。< / p>
Py_INCREF
和Py_DECREF
次出现次数,以了解这种情况的常见程度。