Python 2.7中的代码结果让我感到矛盾。 is
运算符应该与对象标识一起使用,id
也是如此。但是当我查看用户定义的方法时,他们的结果会有所不同。那是为什么?
py-mach >>class Hello(object):
... def hello():
... pass
...
py-mach >>Hello.hello is Hello.hello
False
py-mach >>id(Hello.hello) - id(Hello.hello)
0
我从Python data model的描述中发现以下摘录有点用处。但它并没有真正使一切清楚。如果每次重新构造用户定义的方法对象,为什么id
函数返回相同的整数?
当获取类的属性(可能通过该类的实例),如果该属性是用户定义的函数对象,未绑定的用户定义的方法对象或类时,可以创建用户定义的方法对象方法对象。当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象;否则,原始方法对象按原样使用。
答案 0 :(得分:19)
id function州的Python文档:
返回对象的“标识”。这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。 具有非重叠生命周期的两个对象可能具有相同的id()值。
(强调我的)
执行id(Hello.hello) == id(Hello.hello)
时,方法对象只是短暂创建,在第一次调用'id'后被视为“死”。由于对id
的调用,您只需要Hello.hello
在短时间内活着 - 足以获得ID。一旦你得到那个id,对象就死了,第二个Hello.hello
可以重用那个地址,这使得它看起来好像两个对象具有相同的id。
这与执行Hello.hello is Hello.hello
形成对比 - 两个实例都必须存活足够长时间才能相互比较,因此最终会有两个实时实例。
如果你改为尝试:
>>> a = Hello.hello
>>> b = Hello.hello
>>> id(a) == id(b)
False
...您将获得False
的预期值。
答案 1 :(得分:8)
这是一个简单的"内存分配器如何工作的结果。它与案例非常相似:
>>> id([]) == id([])
True
基本上python并不能保证ID不会被重用 - 它只保证id是唯一的,只要对象是活着的。在这种情况下,传递给id
的第一个对象在调用id
之后死亡,而(C)python在创建第二个对象时重用id
。
不要依赖此行为,因为语言参考允许,但肯定不是必需。