Pythonでオブジェクトの現在の参照カウントを取得する方法はありますか?


93

Pythonでオブジェクトの現在の参照カウントを取得する方法はありますか?

回答:



64

gcガベージコレクターガットへのインターフェイスであるモジュールを使用して、gc.get_referrers(foo)を参照するすべてのリストを取得するために呼び出すことができますfoo

したがって、len(gc.get_referrers(foo))そのリストの長さ、つまりリファラーの数がわかります。これは、あなたが求めているものです。

gcモジュールのドキュメントも参照してください。


7
gcリストもオブジェクトを参照するため、カウントは+1になることにも注意してください。
Richard Levasseur

1
@Danは答えが正しいと思います:>>> import gc >>> class Bar():... pass ... >>> b = Bar()>>> len(gc.get_referrers(b)) 1 >>> gc.get_referrers(B)[{ 'B':<0x7f1f010d0e18で__ main__.Barインスタンス>、 'バー' <クラスメイン0x7f1f010d6530で.BAR>、 'ビルトイン」:<モジュールの組み込み'(組み込みin)>、 'パッケージ':なし、 'gc':<モジュール 'gc'(組み込み)>、 '名前': 'メイン'、 'ドキュメント':なし}]
Havok

2
@tehvanの答え(sys.getrefcount(object))はlen(gc.get_referrers(foo))、本当に数字だけが必要な場合は、よりも簡単です。
moi

Androidのqpython3では、間違った答えが返されます。毎回。
Shihab Shahriar Khan 2017

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()1参照元のリストをフィルタリングする必要がある場合があります。

「変更時の分離」、つまり「他の場所で参照されている場合はクローン」などの目的で、手動の参照カウントを行うことを提案します。


5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypesは、変数のアドレスを引数として取ります。sys.getRefCountよりもctypesを使用する利点は、結果から1を引く必要がないことです。


1
おかしなことに、このメソッドは使用しないでください。1)コードを読んでいる間は誰も何が起こっているのか理解できません。2)CPythonの実装の詳細に依存します。idはオブジェクトのアドレスであり、PyObjectの正確なメモリレイアウトです。必要に応じて、getrefcount()から1を減算するだけです。
ead
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.