Python中重复使用相同的内存位置为a.g
。如果您分配方法的名称,你会看到不同的行为:
# creates a reference to the method f
In [190]: f = a.f
# creates a reference to the method g
In [191]: g = a.g
# cannot reuse the memory location of f as it is still referenced
In [192]: id(f) == id(g)
Out[192]: False
实际上,你真的只需要存储到f参考,看看与上面相同的行为。
In [201]: f = a.f
In [202]: id(f) == id(a.g)
Out[202]: False
你可以看到引用计数与sys.getrefcount
或gc.gc.get_referrers
:
In [2]: import gc
In [3]: f = a.f
In [4]: len(gc.get_referrers(a.g)),len(gc.get_referrers(f))
Out[4]: (0, 1)
In [5]: sys.getrefcount(a.g),sys.getrefcount(f)
Out[5]: (1, 2)
你AG看到1的唯一原因是因为返回的计数是通常一个高于你所期望的,因为它包含(临时)引用作为getrefcount()的参数。 这是类似于你自己的例子,在方法评估后,你仍然可以参考f
,a.g
refcount将为0,因此它立即被垃圾收集,python可以自由地使用内存位置用于其他任何事情。
还值得一提的是,该行为并不局限于方法,但它只是一个CPython的实现细节,不是说你应该永远依靠的东西:
In [67]: id([]), id([])
Out[67]: (139746946179848, 139746946179848)
In [73]: id(tuple()),id([]),id([])
Out[73]: (139747414818888, 139746946217544, 139746946217544)
In [74]: id([]),id([]),id([])
Out[74]: (139746946182024, 139746946182024, 139746946182024)
In [75]: id([]),id(tuple()),id([])
Out[75]: (139746946186888, 139747414818888, 139746946186888)
In [76]: id(tuple()),id([]),id(tuple())
Out[76]: (139747414818888, 139746946217736, 139747414818888)
这是我的理解空的元组是单(实现细节)。所以这不像空列表的例子那样有趣,对我来说无论如何。 –