看看这段代码:
import re
ti = "abcd"
tq = "abcdef"
check_abcd = re.compile('^abcd')
print id(check_abcd.search(ti))
print id(check_abcd.search(tq))
print check_abcd.search(ti)
print check_abcd.search(tq)
if check_abcd.search(ti) is check_abcd.search(tq):
print "Matching"
else:
print "not matching"
输出:
41696976
41696976
<_sre.SRE_Match object at 0x00000000027C3ED0>
<_sre.SRE_Match object at 0x00000000027C3ED0>
not matching
is
的定义:
`is` is identity testing, == is equality testing.
is will return True if two variables point to the same object
1)当id和对象引用相同时,为什么is
不返回True
。
2)当is
被==
替换时,它仍然会返回false
。这是使用==
比较对象时的预期行为。
答案 0 :(得分:6)
您从未分配返回值,因此在打印id()
调用的返回值的check_abcd.search()
值后,Python 会丢弃返回值对象,因为没有任何引用它了CPython对象的生命周期直接由对它们的引用数量决定;一旦引用计数降为0,对象就会从内存中删除。
可以重复使用丢弃的内存位置,因此您希望在id()
来电中看到相同的值。请参阅id()
documentation:
返回对象的“标识”。这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。 两个生命周期不重叠的对象可能具有相同的
id()
值。
在您的代码中,您实际上没有一个对象,您有两个具有非重叠生命周期的独立对象。
如果要确保不重用id()
值,请指定返回值:
>>> import re
>>> ti = "abcd"
>>> tq = "abcdef"
>>> check_abcd = re.compile('^abcd')
>>> ti_search = check_abcd.search(ti)
>>> tq_search = check_abcd.search(tq)
>>> id(ti_search), id(tq_search)
(4378421952, 4378422056)
>>> ti_search, tq_search
(<_sre.SRE_Match object at 0x104f96ac0>, <_sre.SRE_Match object at 0x104f96b28>)
>>> ti_search is tq_search
False
通过分配check_abcd.search()
(正则表达式MatchObject
s)的返回值,将创建一个额外的引用,并且Python无法重用内存位置。
答案 1 :(得分:2)
你做什么:
print id(check_abcd.search(ti))
在一行中,并且不会将search
的返回值存储在任何位置,其引用计数将归零并且会被销毁。线路中的调用创建了另一个对象,该对象恰好位于相同的内存地址中(CPython将其用作对象ID) - 但它不是同一个对象。
当您使用is
运算符时,仍然必须存在上一个对象才能进行比较,并且其地址将不同。
在打印ID(并使用不同的变量)之前,只需将调用结果放入变量check_abcd.search
,您就能看到实际发生的情况。
此外:如果你想了解&#34;是&#34;的行为,继续这些方面可能是有益的。和对象ID - 但是如果你想比较字符串和返回值,只需使用==
运算符,从不is
:后续函数调用,即使返回相同的值也不应该返回相同的值object - 仅在与&#34; None&#34;进行比较时才建议进行is
比较。 (实现为单身)
答案 2 :(得分:2)
Martjin已经给出了正确的答案,但是为了进一步澄清,这里有一个带注释的版本代码中发生了什么:
# this line creates returns a value from .search(),
# prints the id, then DISCARDS the value as you have not
# created a reference using a variable.
print id(check_abcd.search(ti))
# this line creates a new, distinct returned value from .search()
# COINCIDENTALLY reusing the memory address and id of the last one.
print id(check_abcd.search(tq))
# Same, a NEW value having (by coincidence) the same id
print check_abcd.search(ti)
# Same again
print check_abcd.search(tq)
# Here, Python is creating two distinct return values.
# The first object cannot be released and the id reused
# because both values must be held until the conditional statement has
# been completely evaluated. Therefore, while the FIRST value will
# probably reuse the same id, the second one will have a different id.
if check_abcd.search(ti) is check_abcd.search(tq):
print "Matching"
else:
print "not matching"