¿Cuándo se disminuye el recuento de referencia de una variable local en una función de Python?
Tengo la siguiente función:
def myfn():
big_obj = BigObj()
result = consume(big_obj)
return result
¿Cuándo se incrementa/disminuye el recuento de referencias para el valor de BigObj()?
¿Es en:
1. cuando se llama a consume(big_obj)
(ya que big_obj no se referencia posteriormente en myfn)
2. cuando la función retorna
3. algún punto, aún no lo sé
¿Habría alguna diferencia si se cambia la última línea a:
return consume(big_obj)
Edición (aclaración para los comentarios):
- Una variable local existe hasta que la función retorna
- La referencia puede ser eliminada con
del obj
Pero ¿qué sucede con los temporales (por ejemplo, f1(f2())?
Verifiqué las referencias a los temporales con este código:
import sys
def f2(c):
print("f2: Referencias a c", sys.getrefcount(c))
def f0():
print("f0")
f2(object())
def f1():
c = object()
print("f1: Referencias a c", sys.getrefcount(c))
f2(c)
f0()
f1()
Esto imprime:
f0
f2: Referencias a c 3
f1: Referencias a c 2
f2: Referencias a c 4
Parece que las referencias a las variables temporales se mantienen. Ten en cuenta que getrefcount
devuelve uno más de lo que se esperaría porque también mantiene una referencia.
davy.ai
El recuento de referencias para el valor de BigObj() se incrementa cuando se ejecuta la línea
big_obj = BigObj()
, creando una nueva instancia de BigObj() y asignándola a la variable big_obj. El recuento de referencias para el valor de BigObj() se reduce cuando la variable local big_obj sale de alcance, lo cual ocurre cuando la función retorna.En el código dado, el recuento de referencias no se modificaría si la última línea se cambia a
return consume(big_obj)
, ya que el recuento de referencias sigue disminuyendo cuando la variable local big_obj sale de alcance al final de la función.En cuanto a los temporales, el recuento de referencias para los objetos temporales creados dentro de una función se incrementa cuando se crea el objeto y se asigna a una variable, y se reduce cuando la variable sale de alcance (ya sea al final de la función o cuando se elimina la variable con del). Si el objeto temporal se pasa a otra función como argumento, el recuento de referencias también se incrementa temporalmente mientras esa función se está ejecutando.
El código de ejemplo proporcionado muestra que las referencias a los objetos temporales se mantienen hasta el final de la función o hasta que se eliminan explícitamente. La función
getrefcount()
devuelve uno más de lo esperado porque incluye una referencia mantenida por la propia llamada a la función.