Question

The original problem i am dealing with is outlined here. I would like to ask an additional question (about Python reference counting) related to the original problem.

Lets say that i have the following script:

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)

Does the reference count of list1, list2 or any of the objects in either lists changes at some point when i call calculate(list1,list2)?

Just to clarify: I do not mean if the reference count will be the same before and after calling calculate(list1,list2). I mean if the reference count changes at any point during the execution of calculate(list1,list2).

Was it helpful?

Solution

The reference count of list1 and list2 doesn't change, they are just variables and thus string keys in a locals() namespace.

The Python list objects that these two variables point to, though, yes, their reference count changes when passed to a function. During the call to the function two new variables refer to those lists (l1 and l2) increasing the count, and when the function returns those variables are cleaned up and the ref count goes down again.

Inside the calculate() function, you are accessing items of these two lists (l1[0], etc.). Item access could use the __getitem__ method of objects; methods are created on-the-fly when accessed, and hold a reference to the instance and the underlying function. For a list that is another reference to the list object, and another temporary reference count increase. Once the function has been called and returned it's value, the method is discarded again (nothing is referencing it) and the ref count for the list drops again.

As delnan rightly points out in the comments, for list subscription the BINARY_SUBSCR opcode optimizes access (provided the index is an integer) and no method is created in that specific case.

The python interpreter, when handling bytecode and values on the stack, is increasing and decreasing reference counts all the time though. Take a look through the Python bytecode evaluation loop and count the number of Py_INCREF and Py_DECREF occurrences to to get an idea of how common this is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top