Existe-t-il un moyen d'obtenir le nombre de références actuel d'un objet en Python?

93

Existe-t-il un moyen d'obtenir le nombre de références actuel d'un objet en Python?

GEOCHET
la source

Réponses:

109

Selon la documentation Python , le sysmodule contient une fonction:

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

Généralement 1 supérieur à ce à quoi vous pourriez vous attendre, en raison de la référence temp de l'objet arg.

Tehvan
la source
Lien vers la documentation officielle: docs.python.org/2/library/sys.html#sys.getrefcount
moi
64

En utilisant le gcmodule, l'interface avec les tripes du ramasse-miettes, vous pouvez appeler gc.get_referrers(foo)pour obtenir une liste de tout ce qui fait référence foo.

Par conséquent, len(gc.get_referrers(foo))vous donnera la longueur de cette liste: le nombre de référents, ce que vous recherchez.

Voir également la gcdocumentation du module .

kquinn
la source
7
Il convient également de mentionner que le nombre sera de +1, car la liste gc fait également référence à l'objet.
Richard Levasseur le
1
Je pense que @Dan que la réponse est correcte: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar instance à 0x7f1f010d0e18>, 'Bar': <class main .Bar à 0x7f1f010d6530>, ' builtins ': <module ' builtin ' ( intégré- in)>, ' package ': None, 'gc': <module 'gc' (built-in)>, ' name ': ' main ', ' doc ': None}]
Havok
2
La réponse de @ tehvan ( sys.getrefcount(object)) est plus simple que len(gc.get_referrers(foo))si vous n'avez vraiment besoin que du nombre.
moi
dans qpython3 d'Android, il donne une mauvaise réponse. à chaque fois.
Shihab Shahriar Khan
9

Il y a gc.get_referrers()et sys.getrefcount(). Mais, il est un peu difficile de voir comment sys.getrefcount(X)pourrait servir l'objectif du comptage de références traditionnel. Considérer:

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)

Puis function(SomeObject)livre «7»,
sub_function(SomeObject)livre «5»,
sub_sub_function(SomeObject)livre «3» et
sys.getrefcount(SomeObject)livre «2».

En d'autres termes: si vous utilisez, sys.getrefcount()vous devez connaître la profondeur de l'appel de fonction. Car gc.get_referrers()il faudra peut-être filtrer la liste des référents.

Je proposerais de faire un comptage manuel des références à des fins telles que «isolement en cas de changement», c'est-à-dire «cloner si référencé ailleurs».

Frank-René Schäfer
la source
5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes prend l'adresse de la variable comme argument. L'avantage d'utiliser ctypes par rapport à sys.getRefCount est que vous n'avez pas besoin de soustraire 1 du résultat.

Gautam Vanama
la source
1
Bien que drôle, cette méthode ne doit pas être utilisée: 1) personne ne comprendra ce qui se passe lors de la lecture du code 2) cela dépend des détails d'implémentation de CPython: id étant l'adresse de l'objet et la disposition exacte de la mémoire d'un PyObject. Soustrayez simplement 1 à getrefcount () si nécessaire.
lire le