¿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?

Respuestas:



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 .


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".


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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.