Чи є спосіб отримати поточну кількість посилань об’єкта в 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документацію до модуля .


7
Слід також зазначити, що підрахунок буде +1, оскільки список gc також посилається на об'єкт.
Річард Левассер

1
Я думаю, що @Dan, що відповідь правильна: >>> імпортувати gc >>> клас Bar (): ... передати ... >>> 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 ': Немає, 'gc': <модуль 'gc' (вбудований)>, ' name ': ' main ', ' doc ': None}]
Havok

2
Відповідь @ tehvan ( sys.getrefcount(object)) є більш простою, ніж len(gc.get_referrers(foo))якщо вам дійсно потрібен лише номер.
moi

в qpython3 для Android це дає неправильну відповідь. кожного разу.
Shihab Shahriar Khan

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: ідентифікатор - це адреса об’єкта та точне розташування пам’яті PyObject. Просто витягніть 1 із getrefcount (), якщо потрібно.
ead
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.