Почему 'a' + 'bc' приводит к отличной (не is) строке от 'abc'?
Я пытался выяснить, почему следующие "х" и "у" отличаются.
>>> x = 'a'
>>> x += 'bc'
>>> x
'abc'
>>> y = 'abc'
>>> x is y
False
>>>
>>> id(x)
4537718624
>>> id(y)
4537059288
>>>
Почему идентификатор отличается? Я не ищу информацию об операторе is. Я пытаюсь выяснить, почему новый объект, созданный после объединения, отличается от 'y'.
1 ответ
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."