1

我正在处理的原始问题在此处概述。我想问一个与原始问题相关的附加问题(关于 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)

4

1 回答 1

3

list1和的引用计数list2不会改变,它们只是变量,因此是locals()命名空间中的字符串键。

但是,这两个变量指向的 Python 列表对象是的,它们的引用计数在传递给函数时会发生变化。在调用函数期间,两个变量引用那些列表 (l1l2) 增加计数,当函数返回时,这些变量被清除并且引用计数再次下降。

calculate()函数内部,您正在访问这两个列表(l1[0]等)的项目。项目访问可以使用__getitem__对象的方法;方法是在访问时动态创建的,并保存对实例和底层函数的引用。对于一个列表,它是对列表对象的另一个引用,并且另一个临时引用计数增加。一旦函数被调用并返回它的值,该方法将再次被丢弃(没有任何东西引用它)并且列表的引用计数再次下降。

正如 delnan 在评论中正确指出的那样,对于列表订阅,BINARY_SUBSCR操作码优化了访问(假设索引是整数),并且在特定情况下没有创建任何方法。

python 解释器在处理堆栈上的字节码和值时,一直在增加和减少引用计数。查看Python 字节码评估循环并计算出现次数Py_INCREFPy_DECREF出现次数,以了解这种情况的常见程度。

于 2013-01-03T11:05:57.163 回答