为什么 'a' + 'bc' 与 'abc' 结果不同(非同一字符串)?
我在想,为什么下面的 'x' 和 'y' 会不一样。
>>> x = 'a'
>>> x += 'bc'
>>> x
'abc'
>>> y = 'abc'
>>> x is y
False
>>>
>>> id(x)
4537718624
>>> id(y)
4537059288
>>>
为什么它们的 ID 不一样呢?我不是想了解 'is' 这个操作符。我想搞清楚为什么在拼接后新创建的对象和 'y' 会不同。
1 个回答
6
is
是用来判断身份的,意思是对象的身份是什么。而 ==
是用来判断两个对象的值是否相等,也就是说它们的内容是否一样。
如果我改变了 x 的值,y 的值不会改变,因为它们不是同一个对象,尽管它们的值是一样的。另一方面,如果我这样做:
x = [1, 2, 3]
y = x
然后改变其中一个的某些内容,我实际上是在改变 x 和 y 所指向的底层对象。这些只是指向底层对象的标签(引用),而不是对象本身,身份 和 值 是不同的概念。
补充:
想象一下我们创建一个叫做 Person 的类:
class Person(object):
def __init__(name):
self.name = name
世界上有不止一个“乔·史密斯”。但他们不是同一个人。在 Python 中也是如此:
joe1 = Person("Joe Smith")
joe2 = Person("Joe Smith")
他们的身份是不同的,因为它们是不同的对象,尽管它们的名字值是一样的。我们可以为它们创建一个比较操作符,检查名字值是否相等,这样 joe1 == joe2
会返回真,但 joe1 is joe2
永远不会相同。
这个 Python 的特性在你需要知道改变一个对象的状态是否会影响其他地方时非常有用。例如,如果我把一个字典传入一个函数,并改变了这个字典的某些内容,那么这个字典在所有地方都会被改变。这一点特别重要,因为 Python 有时是通过值传递参数,有时是通过引用传递参数,这可能会导致一些难以追踪的错误(尤其是你刚接触 Python 的时候):
>>> foo = {'bar': 'baz'}
>>> def changeit(z):
... z['spam'] = 'eggs'
...
>>> changeit(foo)
>>> foo
{'bar': 'baz', 'spam': 'eggs'}
>>> def changeit2(z):
... if z is foo:
... return "We don't want to mess with this, it affects global state."
... else:
... z['cro'] = 'magnon'
...
>>> changeit2(foo)
"We don't want to mess with this, it affects global state."