¿Hay alguna forma de obtener el recuento de referencias actual de un objeto en Python?

93

¿Hay alguna forma de obtener el recuento de referencias actual de un objeto en Python?

GEOCHET
fuente

Respuestas:

109

Según la documentación de Python , el sysmódulo contiene una función:

import sys
sys.getrefcount(object) #-- Returns the reference count of the object.

Generalmente 1 más alto de lo que cabría esperar, debido a la referencia temporal del objeto arg.

tehvan
fuente
Enlace a la documentación oficial: docs.python.org/2/library/sys.html#sys.getrefcount
moi
64

Usando el gcmódulo, la interfaz para las tripas del recolector de basura, puede llamar gc.get_referrers(foo)para obtener una lista de todo lo que se refiere afoo .

Por lo tanto, len(gc.get_referrers(foo)) le dará la longitud de esa lista: el número de referencias, que es lo que busca.

Consulte también la gcdocumentación del módulo .

kquinn
fuente
7
También se debe mencionar que el recuento será +1, ya que la lista gc también se refiere al objeto.
Richard Levasseur
1
Creo @Dan que la respuesta es correcta: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar instancia en 0x7f1f010d0e18>, 'Bar': <class main .Bar en 0x7f1f010d6530>, ' builtins ': <módulo ' interno ' (integrado in)>, ' package ': None, 'gc': <module 'gc' (built-in)>, ' name ': ' main ', ' doc ': None}]
Havok
2
La respuesta de @ tehvan ( sys.getrefcount(object)) es más sencilla que len(gc.get_referrers(foo)), si realmente solo necesita el número.
Moi
en qpython3 de Android, da una respuesta incorrecta. cada vez.
Shihab Shahriar Khan
9

Hay gc.get_referrers()y sys.getrefcount(). Pero, es un poco difícil ver cómo sys.getrefcount(X)podría servir al propósito del conteo de referencias tradicional. Considerar:

import sys

def function(X):
    sub_function(X)

def sub_function(X):
    sub_sub_function(X)

def sub_sub_function(X):
    print sys.getrefcount(X)

Luego function(SomeObject)entrega '7',
sub_function(SomeObject)entrega '5',
sub_sub_function(SomeObject)entrega '3' y
sys.getrefcount(SomeObject) entrega '2'.

En otras palabras: si lo utiliza sys.getrefcount(), debe conocer la profundidad de la llamada a la función. porgc.get_referrers() posible que tenga que filtrar la lista de referencias.

Propondría hacer un recuento manual de referencias para propósitos tales como "aislamiento en el cambio", es decir, "clonar si se hace referencia a otra parte".

Frank-Rene Schäfer
fuente
5
import ctypes

my_var = 'hello python'
my_var_address = id(my_var)

ctypes.c_long.from_address(my_var_address).value

ctypes toma la dirección de la variable como argumento. La ventaja de usar ctypes sobre sys.getRefCount es que no es necesario restar 1 del resultado.

Gautam Vanama
fuente
1
Si bien es divertido, este método no debe usarse: 1) nadie entenderá lo que está sucediendo mientras lee el código 2) depende de los detalles de implementación de CPython: id es la dirección del objeto y el diseño de memoria exacto de un PyObject. Simplemente reste 1 de getrefcount () si es necesario.
ead