id()
内置函数给出了......
一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。
is
运算符代替......
对象标识
那么为什么有两个具有相同id
但返回False
到is
支票的对象呢?这是一个例子:
>>> class Test():
... def test():
... pass
>>> a = Test()
>>> b = Test()
>>> id(a.test) == id(b.test)
True
>>> a.test is b.test
False
一个更令人不安的例子:(继续上述)
>>> b = a
>>> b is a
True
>>> b.test is a.test
False
>>> a.test is a.test
False
然而:
>>> new_improved_test_method = lambda: None
>>> a.test = new_improved_test_method
>>> a.test is a.test
True
答案 0 :(得分:56)
>>> b.test is a.test
False
>>> a.test is a.test
False
每次查找时都会即时创建方法。函数对象(始终是同一个对象)实现descriptor protocol,其__get__
创建绑定的方法对象。没有两个绑定方法通常是同一个对象。
>>> id(a.test) == id(b.test)
True
>>> a.test is b.test
False
这个例子具有欺骗性。第一个结果只是巧合True
。 a.test
创建绑定方法,并在计算id(a.test)
后收集垃圾,因为没有任何引用它。 (请注意,您引用文档说明id对于此对象在其生命周期中是唯一且常量的“(强调我的)。)b.test
发生到与之前绑定的方法具有相同的ID,并允许它,因为现在没有其他对象具有相同的ID。
请注意,您应该很少使用is
,甚至更少使用id
。 id(foo) == id(bar)
总是错的。
关于你的新例子,希望你能得到它现在所做的:
>>> new_improved_test_method = lambda: None
>>> a.test = new_improved_test_method
>>> a.test is a.test
True
在这种情况下,我们不会动态地从类上的函数自动绑定self和返回绑定方法对象。在这种情况下,您只需将函数存储为实例属性。查找没有什么特别的事情(只有在查找类属性时才会调用描述符),因此每次查找属性时,都会获得存储的原始对象。