【问题标题】:Python, what is the object method of built-in id()?Python,内置id()的对象方法是什么?
【发布时间】:2013-04-22 17:50:21
【问题描述】:

在 Python 中:

  • len(a) 可以替换为 a.__len__()
  • str(a)repr(a) 可以替换为 a.__str__()a.__repr__()
  • ==__eq__+__add__,等等。

是否有类似的方法来获取 id(a) ?如果没有,是否有任何解决方法可以在不使用 id() 的情况下获取 python 对象的唯一 ID?


编辑: 附加问题:如果不是?有什么理由不定义__id__() 吗?

【问题讨论】:

  • 您不能覆盖id 的行为。你想完成什么?
  • 否,因为 id 表示对象在内存中的位置。
  • @segfolt 在 CPython 中,是的,但 Python 语言本身并不能保证这一点。
  • @BrenBarn 我正在尝试重新定义它的行为或模仿它,为其添加一些功能,最后我想要一个唯一的 id。更重要的是,我想了解它是如何工作的。例如代码在没有内置方法的沙箱中运行,我不想依赖它。

标签: python built-in python-internals


【解决方案1】:

不,此行为无法更改。 id() 用于获取“一个整数(或长整数),该整数(或长整数)保证此对象在其生命周期内是唯一且恒定的”source)。这个整数没有其他特殊含义(在 CPython 中,它是存储对象的内存位置的地址,但在可移植 Python 中不能依赖此地址)。

由于id()的返回值没有特殊含义,所以允许你返回不同的值是没有意义的。

此外,虽然您可以保证id() 将为您的自己的 对象返回唯一整数,但您不可能满足全局唯一性约束,因为您的对象不能可能了解所有其他生物。您的一个特殊值可能(并且很可能)与运行时中另一个活动对象的身份发生冲突。这不是可接受的方案。

如果你需要一个有特殊含义的返回值,那么你应该在适当的地方定义一个方法并从中返回一个有用的值。

【讨论】:

  • 我认为 id() 在全球范围内是非常独特的......因为它是对象的内存地址。如果另一个对象具有相同的值,它应该是对现有对象的引用......否则我误解了你的。如果不是出于“唯一标识”的目的,为什么 id() 应该首先存在?除此之外,我相信我既不能重新定义它的行为,也不能以任何其他方式模仿它的行为。
  • @w00d id() 的返回值不必是对象的内存地址。它在 CPython 上,因为使用地址作为 id 很方便,因为它保证是唯一的。但是 CPython 并不是唯一的 Python 实现,Python 的实现可以为id() 使用 任何它想要的值,只要两个同时存活的对象没有相同的 id,并且一个特定对象的 id 永远不会改变。按顺序编号的 ID 与实现一样有效。
  • 是的,id() 可用于验证两个变量是否引用了完全相同的对象。这是身份值的一种可能用途,是的,唯一标识正是为什么存在id()。您最初的问题是关于提供自定义方法以在您对此类对象调用 id() 时提供替代值,而我的回答解释了为什么这是不可能的。
【解决方案2】:

一个对象不知道它自己的名字(它可以有很多),更不用说它关联的任何唯一 ID。所以 - 简而言之 - 不。 __len__ 和合作的原因。工作是它们已经绑定到对象 - 对象没有绑定到它的 ID。

【讨论】:

  • 一个对象可以携带 a 唯一ID就好了(并且id()分配的唯一ID与引用该对象的名称完全无关,所以我不不知道这有什么关系)。该语言只是不提供对该特定 ID 的写入访问权限(并要求以一种不寻常的方式读取它)。事实上,无论你想到什么意思,对象都绑定到它们的id()——它在对象的整个生命周期内都是不变且唯一的。
  • @delnan 是的 - 但我的意思是该对象不知道它已分配的任何 ID(也不需要)。 ID 将在对象创建/分配时以实现认为合适的任何方式生成。 OP 正在询问是否有等效的 __magic__ 方法 - 其中 没有 因为它是在较低级别处理的,所以没有办法本身知道它的 ID 是什么...
  • 你所说的一半是混淆无关的问题,另一半是使用低级实现细节来争论高级功能。为什么不能有一个 object.__id__ 返回实现的 ID 但可以被覆盖?其他方面也是类似的,比如属性访问。
  • 是的..我想知道和@delnan一样的东西为什么不应该是__id__()来覆盖?
  • 绝对不应该有这样的事情(绝对没有用,很有可能搞砸事情,使相当基本的操作变得更加复杂)。但是,可能存在,这就是我们在这里讨论的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2017-03-20
相关资源
最近更新 更多