C'è un modo per ottenere il conteggio ref corrente di un oggetto in Python?


93

C'è un modo per ottenere il conteggio ref corrente di un oggetto in Python?

Risposte:



64

Usando il gcmodulo, l'interfaccia per le budella del garbage collector, puoi chiamare gc.get_referrers(foo)per ottenere un elenco di tutto ciò a cui si riferisce foo.

Quindi, len(gc.get_referrers(foo))ti fornirà la lunghezza di quella lista: il numero di referrer, che è quello che stai cercando.

Vedere anche la gcdocumentazione del modulo .


7
Va anche detto che il conteggio sarà +1, poiché anche l'elenco gc si riferisce all'oggetto.
Richard Levasseur

1
Penso che @ Dan che la risposta sia corretta: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar instance at 0x7f1f010d0e18>, 'Bar': <class main .Bar at 0x7f1f010d6530>, ' builtins ': <module ' builtin ' (built- in)>, ' package ': None, 'gc': <module 'gc' (built-in)>, ' name ': ' main ', ' doc ': None}]
Havok

2
La risposta di @ tehvan ( sys.getrefcount(object)) è più semplice di len(gc.get_referrers(foo)), se hai davvero bisogno solo del numero.
moi

in qpython3 di Android, dà una risposta sbagliata. ogni volta.
Shihab Shahriar Khan

9

C'è gc.get_referrers()e sys.getrefcount(). Ma è un po 'difficile vedere come sys.getrefcount(X)potrebbe servire allo scopo del tradizionale conteggio dei riferimenti. Prendere in considerazione:

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)

Quindi function(SomeObject)consegna "7",
sub_function(SomeObject)"5",
sub_sub_function(SomeObject)"3" e
sys.getrefcount(SomeObject)"2".

In altre parole: se si utilizza sys.getrefcount()è necessario essere consapevoli della profondità della chiamata di funzione. Per gc.get_referrers()uno potrebbe essere necessario filtrare l'elenco dei referrer.

Proporrei di fare il conteggio manuale dei riferimenti per scopi come "isolamento al cambiamento", cioè "clone se referenziato altrove".


5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes prende l'indirizzo della variabile come argomento. Il vantaggio dell'utilizzo di ctypes rispetto a sys.getRefCount è che non è necessario sottrarre 1 dal risultato.


1
Sebbene divertente questo metodo non dovrebbe essere usato: 1) nessuno capirà cosa sta succedendo durante la lettura del codice 2) dipende dai dettagli di implementazione di CPython: id è l'indirizzo dell'oggetto e l'esatto layout di memoria di un PyObject. Basta sottrarre 1 da getrefcount () se necessario.
Leggi il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.