我有以下脚本:
class A(object):
def f(self):
pass
a = A()
b = A()
print map(id, [A.f, a.f, b.f])
print map(id, [a.f, b.f])
输出:
[4299312976, 4298026672, 4299370816]
[4299312976, 4298026672]
id
的{{1}}成为A.f
的{{1}}?id
的{{1}}成为a.f
的{{1}}?现在我这样做:
id
输出:
a.f
为什么他们现在有id
?
答案 0 :(得分:4)
当您访问A.f
时,会创建一个<unbound method>
类型的对象。您可以看到以下情况:
print map(id, [A.f, A.f, A.f])
其中id
值不相同。 a.f
和b.f
也是如此,但在这种情况下类型为<bound method>
,因为对象会记住代码需要对哪个实例进行操作。
一旦您不再引用它们,这些对象就会被垃圾收集。所以:
map(id, [A.f, a.f, b.f])
创建3个对象(4个包含包含它们的列表)并将它们传递给函数id
。一旦map
调用终止,列表就会收集对象并释放内存。
在第二次调用中,创建了新对象,并且已经重用了为A.f
创建的对象的内存(因此你得到了id
)。
在最后一个示例中,每次显式调用一个立即丢弃的对象时,都会调用id
,并且内存恰好会立即重用。
当访问方法时,这显然是“神奇的”对象创建是因为descriptors。