【问题标题】:Python id of name and '__main__' different名称的 Python id 和 '__main__' 不同
【发布时间】:2012-05-17 15:59:10
【问题描述】:

通常,如果我为变量分配一些值,然后检查它们的 id,我希望它们是相同的,因为 python 本质上只是给我的对象一个“名称”。这可以在下面的代码中看到:

>>> a = 3
>>> id(a)
19845928
>>> id(3)
19845928

问题是当我对“name”执行相同操作时

>>> __name__
'__main__'
>>> id(__name__)
19652416
>>> id('__main__')
19652448

id怎么可能不同,不应该一样吗?因为__name__ 也应该只是一个参考。

【问题讨论】:

  • (id("__main__") == id(__name__)) == True
  • 那为什么在空闲时显示不同??
  • @JakobBowyer:您的评论在我的 Cpython(和 pypy)上评估为 False,所以不要责怪 IDLE。
  • @JakobBowyer:这不是真的。不要混淆这个家伙。原因是虽然等值字符串可能具有相同的内存指针,但不能保证它们是相同的。确切的行为是未定义的。
  • 这就是为什么成语是__name__ == '__main__'。检查逻辑(字符串)相等,而不是对象标识。

标签: python


【解决方案1】:

id() 本质上给出了指向数据的内存指针。尽管字符串是不可变的,但不能保证它们会被实习。这意味着一些具有相同值的字符串具有不同的指针。

对于整数(尤其是小整数),指针将是相同的,因此您的 3 示例可以正常工作。


@KartikAnand:您检查“相同对象”的方式是有效的,尽管通常的方式是使用x is y。问题是它们不是同一个对象,并且不能保证是。它们只是具有相同的值。请注意,当您执行"__main__" 时,您正在创建一个新对象。有时,python 会进行很好的优化并重新使用先前创建的具有相同值的字符串,但它没有


Kartik 的目标是“验证分配是否以某种方式引用并且对象不是动态创建的”。为此,请避免创建新对象(无字符串文字)。

>>> __name__
'__main__'
>>> x = __name__
>>> id(__name__)
3078339808L
>>> id(x)
3078339808L
>>> __name__ is x
True

【讨论】:

  • +1 for is -- 我正要说同样的话。但我不确定hash - 不清楚 OP 是否希望散列任何内容。
  • hash() 将在 id() 失败的情况下工作,这就是我要说的。他似乎想要一个可以比较相等对象的整数。
  • 这有助于证明id() 给出了一个对象的内存地址(指针):code.activestate.com/recipes/578132
  • @NoctisSkytower:请注意,这是 id() 的实现细节,对于替代解释器或可能的 python 未来版本是不同的。
  • @bukzor 我只是想验证分配是否以某种方式引用并且对象不是动态创建的..我不想比较任何东西..我只是好奇为什么他们的 id 不一样
【解决方案2】:

仅仅因为两个字符串具有相同的值,并不意味着它们是同一个对象。这是完全预期的行为。

【讨论】:

  • 你没有教育过新手。您遗漏了许多理解“答案”所必需的细节。
  • @bukzor 我遗漏了哪些细节?哪些术语需要进一步定义才能理解这个问题?
  • 主要是他好像不知道有两个字符串。
  • @bukzor 所以......你在我的回答中没有看到“两个字符串”这个词吗?
  • 这不是问题,是吗?作为OP,它是没有先例的参考。他显然在他的例子中只看到了一个字符串。
【解决方案3】:

在 Python 中,小整数是“池化”的,因此所有小整数值都指向同一个对象。这对于字符串来说不是必须的。

无论如何,这是一个不应该依赖的实现细节。

【讨论】:

  • 那么我如何检查它们是否引用了相同的对象??
  • 通常你要检查它们是否是相同的,在这种情况下你可以使用==
  • @KartikAnand,你为什么关心它们是否引用同一个对象?
  • 我知道我可以使用它,但是看到 python 使用引用而不是创建新对象不应该有一种技术来保持检查吗?我一直认为 id 可以提供帮助
  • @KartikAnand 你的实际用例是什么?正如许多人所说,大多数时候,您是在寻找价值,而不是对象比较。
【解决方案4】:

您在这里遇到的事实是,原语是 Python 中的伪(或真实)单例。此外,查看字符串会掩盖问题,因为当字符串被实习时,值和 id 会成为副作用的同义词,因此某些具有值匹配的字符串将具有 id 匹配,而另一些则不会。尝试查看手工构建的对象,这样您就可以控制何时创建新实例,并且 id 与 value 变得更加清晰。

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2019-12-19
    • 2014-10-22
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多