【问题标题】:When do undeclared objects get ids?未声明的对象何时获得 id?
【发布时间】:2012-12-13 15:40:33
【问题描述】:

理论题

每个 Python shell 都有无需声明或创建即可使用的对象,例如 True、False、""、[]、{},以及整数和浮点数的任意组合。

这意味着您可以随时获取他们的 ID。

id(1)
id(42)
id('')

等等

当然,如果你尝试获取一个未声明对象的 id,你会得到:

id(myobject1)

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    id(myobject1)
NameError: name 'myobject1' is not defined

因为 myobject1 没有指向任何东西,所以它没有被定义,也没有 id。

然而,有无限数量的对象可以在没有声明的情况下使用,因为数字系统是无限的。因此,在程序中以某种身份使用之前,所有未声明的对象都不可能具有 id。

这些对象何时获得分配 ID?

【问题讨论】:

    标签: python theory


    【解决方案1】:

    你误解了赋值的概念。

    在分配中,您将对象绑定到名称。所有分配给的名称都可以以任何想要的方式使用,未分配的名称不存在,因此不能指向任何东西(包括“无处”)。

    使用id(spam),您可以询问spam指向的对象,然后询问其ID。

    一个不存在的名称spam 没有分配给它的对象,其ID 可以被查询。

    OTOH,每个对象都有一个 ID。

    【讨论】:

    • 好的,所以一个未声明的“对象”(实际上根本不是对象)是一个尚未绑定到对象的不存在指针。但是像 42 这样有 id 的对象呢?由于缺少更好的术语,该 id 在什么时候“生成”?是第一次使用吗?
    • 我认为这里的最后一个概念飞跃是对于内置类型,至少在这个问题的上下文中,字面值可以被认为是实例化和赋值的语法简写。因此说42 有点像42 = int(42)。由此,id(42) 可以被认为是id(int(42))
    • @BenMordecai 创建一个对象。我可以在不保留对象的情况下获取对象的 ID。使用id(object()) 创建一个对象,获取它的 ID 并立即丢弃它。 142'' 要么在您使用它们时创建(或在调用它们所在的函数时创建),但之后它们仍保持为单例。
    • 字符串文字和整数不是单例。解释器缓存其中的一些(默认情况下,如果有记忆,CPython 中的数字在 -5 到 256 之间),所以 id(1) == id(1),但 id(49752) != id(49752)
    • 是的,这只是优化。
    【解决方案2】:

    我将尝试一一反驳这些误解。这可能有用,也可能没用。

    每个 Python shell 都有无需声明即可使用的对象

    Python 中没有“声明”对象的概念。因此,对象既没有声明也没有未声明。

    或创建

    您不能使用未创建的对象。所有存在的对象都有 id。

    对,错

    TrueFalse 是存在的对象。他们有 id。

    ""、[]、{},以及整数和浮点数的任意组合。

    当代码执行时,文字变成对象。字符{} 的组合本质上是说dict() 的快捷方式。创建的对象都有 id。

    当然,如果您尝试获取未声明对象的 id,则会得到 NameError。

    没有。 NameError 是当您尝试使用尚未定义的名称时。

    因为 myobject1 没有指向任何东西

    错了,它并没有“指向任何东西”。它没有被定义。它不能指向任何东西,它不存在。

    并且没有id。

    名称没有 ID。对象有 id。当你说

    >>> foo = 5
    >>> id(foo)
    137396064
    

    您不是在询问名称foo 的ID。您正在询问名称 foo 分配给的对象的 id。如果你现在重新分配 foo,你会得到另一个 id:

    >>> bar = foo
    >>> foo = "string"
    >>> id(foo)
    3075254336
    >>> id(bar)
    137396064
    

    对象的 id 保持不变,名称已重新分配。

    然而,有无数的对象可以在没有声明的情况下使用

    不,他们不是。

    【讨论】:

    • 这是一个值得 300 次投票的答案。你是一个真正了解他的主题的人,而不是每个人的情况......
    【解决方案3】:

    关于 42 何时成为分配的 id 的问题:您可以将 42 视为 int(42)。它为值为 42 的整数分配内存。构造整数后,将其传递给id() 函数。之后,整数的引用计数递减,因此被释放。

    从技术上讲,对象的 id 只是它在内存中的地址。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多