มีวิธีรับจำนวนการอ้างอิงปัจจุบันของวัตถุใน Python หรือไม่?


คำตอบ:


109

ตามที่หลามเอกสารที่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 อ้างถึงวัตถุด้วย
Richard Levasseur

1
ฉันคิดว่า @Dan ตอบถูก >>> import gc >>> class Bar (): ... pass ... >>> b = Bar () >>> len (gc.get_referrers (b)) 1 >>> gc.get_referrers (b) [{'b': <__ main__.Bar อินสแตนซ์ที่ 0x7f1f010d0e18>, 'Bar': <class main .Bar ที่ 0x7f1f010d6530>, ' builtins ': <module ' builtin ' (built- ใน)>, ' package ': ไม่มี, 'gc': <module 'gc' (built-in)>, ' 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: id เป็นที่อยู่ของวัตถุและรูปแบบหน่วยความจำที่แน่นอนของ PyObject เพียงแค่แทนที่ 1 จาก getrefcount () หากจำเป็น
อี๊ด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.