关于实例方法上id的行为

时间:2014-10-05 09:21:52

标签: python python-2.7

我有以下脚本:

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

1 个答案:

答案 0 :(得分:4)

当您访问A.f时,会创建一个<unbound method>类型的对象。您可以看到以下情况:

print map(id, [A.f, A.f, A.f])

其中id值不相同。 a.fb.f也是如此,但在这种情况下类型为<bound method>,因为对象会记住代码需要对哪个实例进行操作。

一旦您不再引用它们,这些对象就会被垃圾收集。所以:

map(id, [A.f, a.f, b.f])

创建3个对象(4个包含包含它们的列表)并将它们传递给函数id。一旦map调用终止,列表就会收集对象并释放内存。

在第二次调用中,创建了新对象,并且已经重用了为A.f创建的对象的内存(因此你得到了id)。

在最后一个示例中,每次显式调用一个立即丢弃的对象时,都会调用id,并且内存恰好会立即重用。

当访问方法时,这显然是“神奇的”对象创建是因为descriptors