【问题标题】:id() and 'is' operator applied to lists in Python [duplicate]id()和'is'运算符应用于Python中的列表[重复]
【发布时间】:2020-08-20 17:45:43
【问题描述】:

id(A) == id(B)A is B 据我了解,被视为 A 和 B 是否引用同一对象的测试。 (见答案和 cmets Understanding Python's "is" operator

但是,应用于列表,我们可以得到以下结果:

>>> id(['a', 'b', 'c']) == id(['a', 'b', 'c'])
True
>>> ['a', 'b', 'c'] is ['a', 'b', 'c']
False

有人能解释一下“幕后”究竟发生了什么以促成这种行为吗?

【问题讨论】:

    标签: python


    【解决方案1】:

    id 函数返回活动对象的唯一标识符。同时存在的两个对象不能具有相同的 id。虽然,文档还提到这不适用于同时不存在的对象。

    生命周期不重叠的两个对象可能具有相同的id() 价值。

    这就是你的情况;当创建第二个列表时,第一个列表不再被引用并且已被释放。

    我们可以通过反汇编您的第一个示例来观察这一点。

    >>> import dis
    >>> def f():
    ...     id([1, 2, 3]) == id([1, 2, 3])
    ... 
    >>> dis.dis(f)
      2           0 LOAD_GLOBAL              0 (id)
                  2 LOAD_CONST               1 (1)
                  4 LOAD_CONST               2 (2)
                  6 LOAD_CONST               3 (3)
                  8 BUILD_LIST               3      # Creation of the first list
                 10 CALL_FUNCTION            1      # After that point the first list is no longer referenced
                 12 LOAD_GLOBAL              0 (id)
                 14 LOAD_CONST               1 (1)
                 16 LOAD_CONST               2 (2)
                 18 LOAD_CONST               3 (3)
                 20 BUILD_LIST               3      # Only here is the second list allocated
                 22 CALL_FUNCTION            1
                 24 COMPARE_OP               2 (==)
                 26 POP_TOP
                 28 LOAD_CONST               0 (None)
                 30 RETURN_VALUE
    

    请注意,对于 cPython,id 返回对象在内存中的位置。因此,您观察到的只是 Python 为两个生命周期不相交的对象重用相同的内存槽。您可以使用完全不相等的列表重现该示例。

    >>> id([1, 2, 3]) == id([4, 5, 6])
    True
    

    【讨论】:

    • 非常感谢您的详细解释!我想知道它应该与对象的生命周期相关联,但开始怀疑它是否会在一个“==”语句中发生。现在很清楚了。
    猜你喜欢
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2014-03-14
    相关资源
    最近更新 更多