Python对对象字段的引用计数

Python对对象字段的引用计数,python,garbage-collection,Python,Garbage Collection,以下代码在Python3的Mac终端上运行: import gc import numpy as np class D(object): def __init__(self): self.value = np.arange(3) def get(self): return self.value d = D() print(gc.get_referrers(d)) print(type(gc.get_referrers(d))) prin

以下代码在Python3的Mac终端上运行:

import gc

import numpy as np

class D(object):

    def __init__(self):
        self.value = np.arange(3)

    def get(self):
        return self.value


d = D()
print(gc.get_referrers(d))
print(type(gc.get_referrers(d)))
print()
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))
print()

l = []
l.append(d)
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))
print()

x = d.value
print(len(gc.get_referrers(d)))
print(len(gc.get_referrers(d.value)))
上述代码将返回:

[{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10de6cef0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test3.py', '__cached__': None, 'gc': <module 'gc' (built-in)>, 'np': <module 'numpy' from '/Users/jkim/Codes/Codes/Notebooks/venv3/lib/python3.6/site-packages/numpy/__init__.py'>, 'D': <class '__main__.D'>, 'd': <__main__.D object at 0x10dec7fd0>}]
<class 'list'>

1
0

2
0

2
1

1.
0
2.
0
2.
1.
谁能给我解释一下:

  • 为什么
    d.value
    0
    ,如果
    d.value
    的引用计数确实是
    0
    ,为什么
    d.value
    没有被Python收集垃圾

  • 对象
    d
    引用的列表究竟是什么

  • 谢谢大家!

  • 参考计数为而不是0。无法在CPython中观察引用计数为0的对象;您需要对对象的引用来对其执行任何操作,并且该引用将计入其引用计数。您所看到的是,没有对象的GC跟踪引用器。如果需要实际引用计数,请使用
    sys.getrefcount
  • 没有引用该对象的列表。您正在获取由
    gc返回的referer列表的类型。获取\u referer
    。此列表本身不是对象的引用
  • d.value
    没有GC跟踪的引用,原因如下。首先,
    d.value
    是一个NumPy数组,其数据类型不能保存对象引用,因此不能参与引用循环。NumPy实现通过使这些数组不受GC跟踪来优化它们


    其次,对
    d.value
    的唯一引用是
    d.\uu dict\uuu
    中的一个引用,以及访问
    d.value
    或将其传递给
    gc.get\u referers
    时创建的临时引用。临时引用位于当前堆栈帧的字节码操作数堆栈或C局部变量中,这些位置对GC不可见
    d.uuu dict\uuuuu
    只保存了无法GC跟踪的对象(数组和
    'value'
    字符串),并且CPython dict实现不会GC跟踪dict,直到插入了能够GC跟踪的键或值(或者在某些情况下,当dict被创建为跟踪dict的副本时).

    为什么要子类化
    对象
    ?这是Python 2吗?如果是这样,请给它贴上标签。这是蟒蛇3。我这样做是出于习惯。谢谢你的编辑