Czy istnieje sposób, aby uzyskać bieżącą liczbę referencji obiektu w Pythonie?


93

Czy istnieje sposób, aby uzyskać bieżącą liczbę referencji obiektu w Pythonie?

Odpowiedzi:



64

Korzystając z gcmodułu, interfejsu do wnętrzności garbage collectora, możesz zadzwonić, gc.get_referrers(foo)aby uzyskać listę wszystkiego, do czego się odnosi foo.

W związku z len(gc.get_referrers(foo))tym podasz długość tej listy: liczbę odsyłających, czyli to, czego szukasz.

Zobacz także gcdokumentację modułu .


7
Należy również wspomnieć, że liczba ta wyniesie +1, ponieważ lista gc również odnosi się do obiektu.
Richard Levasseur

1
Myślę @Dan, że odpowiedź jest poprawna: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar instancja pod adresem 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
Odpowiedź @ tehvana ( sys.getrefcount(object)) jest prostsza niż len(gc.get_referrers(foo)), jeśli naprawdę potrzebujesz tylko liczby.
moi

w qpythonie3 Androida daje złą odpowiedź. każdego razu.
Shihab Shahriar Khan

9

Jest gc.get_referrers()i sys.getrefcount(). Trudno jednak dostrzec, jak sys.getrefcount(X)mogłoby służyć tradycyjnemu zliczaniu referencji. Rozważać:

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)

Następnie function(SomeObject)dostarcza „7”,
sub_function(SomeObject)dostarcza „5”,
sub_sub_function(SomeObject)dostarcza „3” i
sys.getrefcount(SomeObject)dostarcza „2”.

Innymi słowy: jeśli używasz sys.getrefcount(), musisz być świadomy głębokości wywołania funkcji. Być gc.get_referrers()może trzeba będzie przefiltrować listę odsyłających.

Proponuję ręczne zliczanie odniesień do celów takich jak „izolacja przy zmianie”, tj. „Klonowanie, jeśli odwołanie następuje w innym miejscu”.


5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes przyjmuje adres zmiennej jako argument. Zaletą używania ctypes nad sys.getRefCount jest to, że nie musisz odejmować 1 od wyniku.


1
Chociaż zabawna metoda nie powinna być używana: 1) nikt nie zrozumie, co się dzieje podczas czytania kodu 2) zależy to od szczegółów implementacji CPythona: id to adres obiektu i dokładny układ pamięci PyObject. W razie potrzeby odejmij 1 od metody getrefcount ().
ead
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.