Есть ли способ получить текущее количество ссылок объекта в Python?

93

Есть ли способ получить текущее количество ссылок объекта в Python?

ГЕОЧЕТ
источник

Ответы:

109

Согласно документации Python , sysмодуль содержит функцию:

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

Обычно на 1 больше, чем можно было ожидать, из-за ссылки на временный аргумент объекта.

Техван
источник
Ссылка на официальную документацию: docs.python.org/2/library/sys.html#sys.getrefcount
moi
64

Используя gcмодуль, интерфейс к внутренностям сборщика мусора, вы можете позвонить, gc.get_referrers(foo)чтобы получить список всего, к чему относится foo.

Следовательно, len(gc.get_referrers(foo))вы получите длину этого списка: количество рефереров, которые вам нужны.

См. Также gcдокументацию модуля .

Kquinn
источник
7
Также следует отметить, что счетчик будет +1, поскольку список gc также относится к объекту.
Ричард Левассер,
1
Я думаю, @Dan, что ответ правильный: >>> 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
Ответ @ tehvan ( sys.getrefcount(object)) более простой, чем len(gc.get_referrers(foo))если вам действительно нужен только номер.
moi
в Android qpython3 он дает неправильный ответ. каждый раз.
Шихаб Шахриар Хан
9

Есть gc.get_referrers()и sys.getrefcount(). Но трудно понять, как это sys.getrefcount(X)может служить целям традиционного подсчета ссылок. Рассмотреть возможность:

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)

Затем function(SomeObject)доставляет «7»,
sub_function(SomeObject)доставляет «5»,
sub_sub_function(SomeObject)доставляет «3» и
sys.getrefcount(SomeObject)доставляет «2».

Другими словами: если вы используете, sys.getrefcount()вы должны знать глубину вызова функции. Для gc.get_referrers()одного , возможно , придется отфильтровать список рекомендателей.

Я бы предложил сделать ручной подсчет ссылок для таких целей, как «изоляция при изменении», то есть «клонирование, если на него есть ссылка в другом месте».

Франк-Рене Шефер
источник
5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes принимает адрес переменной в качестве аргумента. Преимущество использования ctypes перед sys.getRefCount заключается в том, что вам не нужно вычитать 1 из результата.

Гаутам Ванама
источник
1
Как ни странно, этот метод не следует использовать: 1) никто не поймет, что происходит при чтении кода 2) это зависит от деталей реализации CPython: id - это адрес объекта и точная структура памяти PyObject. При необходимости вычтите 1 из getrefcount ().
ead