【问题标题】:In Python, does this expression "(a is b) == ( id(a) == id(b) )" always return True?在 Python 中,这个表达式“(a is b) == ( id(a) == id(b) )” 总是返回 True 吗?
【发布时间】:2020-07-09 02:07:06
【问题描述】:

在 Python 中,表达式 (a is b) == ( id(a) == id(b) ) 似乎总是返回 True,其中 ab 是引用某个对象的变量,因为 id 函数返回存储它们的内存,而 is 是用于对象标识。

有什么例外吗?

【问题讨论】:

    标签: python python-3.x object object-identity


    【解决方案1】:

    如果您仅使用isNone 进行比较,我相信您应该这样做,那么这个问题是无关紧要的,因为None 有一个明确定义的地址

    >>> id(None)
    10306432
    >>> id(None)
    10306432
    >>> a = None
    >>> id(a)
    10306432
    

    我还没有遇到过a is b产生的结果与id(a) == id(b)不同的情况,但你还是不想随便使用is

    >>> a = 1
    >>> b = 1
    >>> id(a), id(b), id(1)
    (10914496, 10914496, 10914496)
    
    # 1 has a single address, is fails to recognize that a and b were created separately.
    
    >>> a = 500
    >>> b = 500
    >>> id(a), id(b), id(500)
    (140251806972464, 140251806973200, 140251806973744)
    
    # Unlike the previous case, 500 is created multiple times, each with a different address
    
    >>> a, b = 500, 500
    >>> id(a), id(b), id(500)
    (140251806972336, 140251806972336, 140251806972464)
    
    # Several instances during the same initialization are created with a single address
    
    >>> a, b = 500, 5*100
    >>> id(a), id(b), id(500)
    (140251806973104, 140251806973200, 140251806971280)
    
    # However it only works if all are created in the same manner...
    
    >>> a, b = 5*100, 5*100
    >>> id(a), id(b), id(500)
    (140251806971920, 140251806973392, 140251806973104)
    
    # ... and they have to be created explicitely.
    
    
    >>> a = 500 ; b = 500
    >>> id(a), id(b), id(500)
    (140251806973104, 140251806973104, 140251806972464)
    
    # Separating with a semicolon does not change this fact...
    
    >>> 500 is 500
    True
    >>> a is b
    True
    >>> a = 500
    >>> a is 500
    False
    >>> a = 500 ; a is 500
    True
    
    # However being in the same line is not a basis for always having the same address, even if all values were created explicitly :
    
    >>> any([a is 500 for a in [500]])
    False
    

    其他对象都有自己的古怪行为:

    >>> a = 'hello'
    >>> b = 'hello'
    >>> id(a), id(b), id('hello')
    (140251789045408, 140251789045408, 140251789045408)
    
    >>> a = 'hello' + ' '
    >>> b = 'hello' + ' '
    >>> id(a), id(b), id('hello' + ' ')
    (140251789044344, 140251789012472, 140251789012920)
    
    >>> a = []
    >>> b = []
    >>> id(a), id(b), id([])
    (140251789066632, 140251789069704, 140251789174216)
    

    我会得出结论,isid 的行为太不可靠,以至于 (a is b) == (id(a) == id(b)) 没有用处即使它是真的,至少在不可变对象的情况下是这样。

    我个人绝不会想到在任何情况下都使用is

    if x is None:
        pass
    

    我只为可变对象或自定义类保留id

    【讨论】:

      【解决方案2】:
      (a is b) == ( id(a) == id(b) )
      

      这个表达式总是True。 有两种可能的方式: 1.ab都指向同一个对象

      >>>a='Hello'
      >>>b=a
      >>> a is b
      True
      >>> id(a)==id(b)
      True
      
      1. “a”和“b”都引用不同的对象。
      >>>a='hello'
      >>>b='world'
      >>>a is b
      False
      >>>id(a)==id(b)
      False
      

      id(a)==id(b)a is b 所做的事情。

      现在,Incase1 (a is b) == ( id(a) == id(b) ) 这是True==True,它返回True。 在第二种情况下,(a is b) == ( id(a) == id(b) ) 这是False==False,它返回True

      来自Docs

      运算符isis not 测试对象的身份:x is y 当且仅当xy 为真> 是同一个对象。使用id() 函数确定对象的身份。 x 不是 y 产生反真值。

      【讨论】:

      • 您只证明了两个字符串的情况,而不是总是如此。
      • @nnnmmm 你能证明a is b == (id(a)==id(b)) 返回False 的情况吗?对于哪个数据类型,这不包含True
      • @nnnmmm 我完全回答了这个问题。仅当 ab 引用同一个对象时,a is b 才是 True。只有当ab 引用同一个对象时,id(a)==id(b) 才为 True。这就是投反对票的原因?我不明白我还要解释什么。问题不在于is 是如何实现的。
      • @nnnmmm docs 也这么说。此外,关于为什么该表达式总是计算为True 而不是关于如何实现isid 的问题。我真的不明白你投反对票的原因? ;)
      • @nnnmmm id() is defined as the "identity" tag of an objectis is an identity check,它们按规范和定义匹配。
      猜你喜欢
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 2021-08-26
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多