Existe uma maneira de obter a contagem de referência atual de um objeto em Python?

94

Existe uma maneira de obter a contagem de referência atual de um objeto em Python?

GEOCHET
fonte

Respostas:

110

De acordo com a documentação do Python , o sysmódulo contém uma função:

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

Geralmente 1 maior do que o esperado, devido à referência do objeto arg temp.

Tehvan
fonte
Link para a documentação oficial: docs.python.org/2/library/sys.html#sys.getrefcount
moi
65

Usando o gcmódulo, a interface para o coletor de lixo guts, você pode chamar gc.get_referrers(foo)para obter uma lista de tudo que se refere foo.

Portanto, len(gc.get_referrers(foo))fornecerá o comprimento dessa lista: o número de referenciadores, que é o que você procura.

Veja também a gcdocumentação do módulo .

Kquinn
fonte
7
Também deve ser mencionado que a contagem será +1, já que a lista gc também se refere ao objeto.
Richard Levasseur
1
Acho @Dan que a resposta está correta: >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{ 'b': <__ exemplo main__.Bar em 0x7f1f010d0e18>, 'Bar': <class principal .bar no 0x7f1f010d6530>, ' builtins ': <module' embutido ' (built in)>, ' package ': None, 'gc': <module 'gc' (built-in)>, ' name ': ' main ', ' doc ': None}]
Havok
2
A resposta de @tehvan ( sys.getrefcount(object)) é mais direta do que len(gc.get_referrers(foo))se você realmente só precisar do número.
moi de
no qpython3 do Android, dá uma resposta errada. toda vez.
Shihab Shahriar Khan
9

Existe gc.get_referrers()e sys.getrefcount(). Mas, é meio difícil ver como sys.getrefcount(X)poderia servir ao propósito da contagem de referência 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)

Em seguida, function(SomeObject)entrega '7',
sub_function(SomeObject)entrega '5',
sub_sub_function(SomeObject)entrega '3' e
sys.getrefcount(SomeObject)entrega '2'.

Em outras palavras: se você usar, sys.getrefcount()deve estar ciente da profundidade da chamada de função. Para gc.get_referrers()um pode ter para filtrar a lista de referências.

Eu proporia fazer a contagem de referência manual para fins como “isolamento na mudança”, ou seja, “clonar se houver referência em outro lugar”.

Frank-Rene Schäfer
fonte
5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes leva o endereço da variável como um argumento. A vantagem de usar ctypes em vez de sys.getRefCount é que você não precisa subtrair 1 do resultado.

Gautam Vanama
fonte
1
Embora engraçado, esse método não deve ser usado: 1) ninguém entenderá o que está acontecendo durante a leitura do código 2) depende dos detalhes de implementação do CPython: id sendo o endereço do objeto e o layout de memória exato de um PyObject. Apenas subtraia 1 de getrefcount () se necessário.
ead