【发布时间】:2020-07-09 02:07:06
【问题描述】:
在 Python 中,表达式 (a is b) == ( id(a) == id(b) ) 似乎总是返回 True,其中 a 和 b 是引用某个对象的变量,因为 id 函数返回存储它们的内存,而 is 是用于对象标识。
有什么例外吗?
【问题讨论】:
标签: python python-3.x object object-identity
在 Python 中,表达式 (a is b) == ( id(a) == id(b) ) 似乎总是返回 True,其中 a 和 b 是引用某个对象的变量,因为 id 函数返回存储它们的内存,而 is 是用于对象标识。
有什么例外吗?
【问题讨论】:
标签: python python-3.x object object-identity
如果您仅使用is 与None 进行比较,我相信您应该这样做,那么这个问题是无关紧要的,因为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)
我会得出结论,is 和 id 的行为太不可靠,以至于 (a is b) == (id(a) == id(b)) 没有用处即使它是真的,至少在不可变对象的情况下是这样。
我个人绝不会想到在任何情况下都使用is
if x is None:
pass
我只为可变对象或自定义类保留id。
【讨论】:
(a is b) == ( id(a) == id(b) )
这个表达式总是True。
有两种可能的方式:
1.a和b都指向同一个对象
>>>a='Hello'
>>>b=a
>>> a is b
True
>>> id(a)==id(b)
True
>>>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:
运算符
is和is not测试对象的身份:x is y 当且仅当x 和y 为真> 是同一个对象。使用id()函数确定对象的身份。 x 不是 y 产生反真值。
【讨论】:
a is b == (id(a)==id(b)) 返回False 的情况吗?对于哪个数据类型,这不包含True
a 和 b 引用同一个对象时,a is b 才是 True。只有当a 和b 引用同一个对象时,id(a)==id(b) 才为 True。这就是投反对票的原因?我不明白我还要解释什么。问题不在于is 是如何实现的。
True 而不是关于如何实现is 或id 的问题。我真的不明白你投反对票的原因? ;)
id() is defined as the "identity" tag of an object 和 is is an identity check,它们按规范和定义匹配。