Apakah ada cara untuk mendapatkan hitungan ref saat ini dari suatu objek dengan Python?

93

Apakah ada cara untuk mendapatkan hitungan ref saat ini dari suatu objek dengan Python?

GEOCHET
sumber

Jawaban:

64

Menggunakan gcmodul, antarmuka ke nyali pengumpul sampah, Anda dapat memanggil gc.get_referrers(foo)untuk mendapatkan daftar semua yang merujuk foo.

Karenanya, len(gc.get_referrers(foo))akan memberi Anda panjang daftar itu: jumlah pengarah, yang Anda cari.

Lihat juga gcdokumentasi modul .

kquinn
sumber
7
Juga harus disebutkan hitungannya akan menjadi +1, karena daftar gc merujuk ke objek juga.
Richard Levasseur
1
Saya pikir @Dan jawabannya benar: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar instance di 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
@tehvan's answer ( sys.getrefcount(object)) lebih mudah daripada len(gc.get_referrers(foo)), jika Anda benar-benar hanya membutuhkan nomornya.
moi
di qpython3 Android, itu memberikan jawaban yang salah. setiap saat.
Shihab Shahriar Khan
9

Ada gc.get_referrers()dan sys.getrefcount(). Tapi, agak sulit untuk melihat bagaimana sys.getrefcount(X)bisa melayani tujuan penghitungan referensi tradisional. Mempertimbangkan:

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)

Kemudian function(SomeObject)berikan '7',
sub_function(SomeObject)berikan '5',
sub_sub_function(SomeObject)berikan '3', dan
sys.getrefcount(SomeObject)berikan '2'.

Dengan kata lain: Jika Anda menggunakan sys.getrefcount()Anda harus menyadari kedalaman panggilan fungsi. Untuk gc.get_referrers()satu mungkin harus memfilter daftar perujuk.

Saya akan mengusulkan untuk melakukan penghitungan referensi manual untuk tujuan seperti "isolasi pada perubahan", yaitu "klon jika direferensikan di tempat lain".

Frank-Rene Schäfer
sumber
5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes menggunakan alamat variabel sebagai argumen. Keuntungan menggunakan ctypes dibandingkan sys.getRefCount adalah Anda tidak perlu mengurangi 1 dari hasil.

Gautam Vanama
sumber
1
Meskipun lucu, metode ini tidak boleh digunakan: 1) tidak ada yang akan mengerti apa yang terjadi saat membaca kode 2) itu bergantung pada detail implementasi CPython: id menjadi alamat objek dan tata letak memori yang tepat dari PyObject. Kurangi saja 1 dari getrefcount () jika perlu.
ead