【问题标题】:`id` function in Python 2.7, `is` operator, object identity and user-defined methods [duplicate]Python 2.7中的`id`函数,`is`运算符,对象标识和用户定义的方法[重复]
【发布时间】:2014-11-09 03:49:27
【问题描述】:

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函数返回的都是同一个整数?

如果该属性是用户定义的函数对象,未绑定的用户定义的方法对象或类,则可以在获取类的属性(可能通过该类的实例)时创建用户定义的方法对象方法对象。当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象;否则,原样使用原始方法对象。

【问题讨论】:

  • @user2357112 -- 我认为 OP 理解这部分“如果用户定义的方法对象每次都重新构造,为什么 id 函数返回相同的整数?”。更好的欺骗是stackoverflow.com/q/3877230/748858
  • @mgilson:是的,这就是我重新打开的原因。我需要停止如此仓促地使用dupehammer。
  • @user2357112 -- 我更喜欢它,因为它需要更多 4 人同意我的观点,认为这是一个骗局 -- 这些天我更不愿意把这个骗子打倒...

标签: python python-2.7 identity equality


【解决方案1】:

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 的预期值。

【讨论】:

  • 理论上Hello.hello is Hello.hello 可以在向第二个id 询问之前删除它对第一个Hello.hello 的引用。
【解决方案2】:

这是内存分配器工作方式的“简单”结果。和案例很相似:

>>> id([]) == id([])
True

基本上,python 不保证 ID 不会被重用——它只保证 ID 是唯一的只要对象还活着。在这种情况下,传递给id 的第一个对象在调用id 之后就死了,并且(C)python 在创建第二个对象时重用了id

永远不要依赖这种行为,因为语言参考允许,但肯定不是必需

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    相关资源
    最近更新 更多