Почему `| =` видимо мутирует `set`, а длинная форма - нет? - PullRequest
0 голосов
/ 27 октября 2019

Хорошо, мне нужен кто-то, кто знает Python лучше, чем я, чтобы объяснить мне

>>> x = set()
>>> y = x
>>> x = x | set([1])
>>> x
{1}
>>> y
set()

Хорошо, отлично, как и ожидалось, операция | создает новый набор , как описано и присваивает его x. y все еще указывает на оригинал (пусто) set

Итак, это всего лишь условное обозначение, верно?

>>> x = set()
>>> y = x
>>> x |= set([1])

Я ожидаю таких же результатов

>>> x
{1}
>>> y
{1}

WTF !? Это ... задокументировано или ... что?

Ответы [ 2 ]

1 голос
/ 27 октября 2019

Для чего бы это ни стоило, это также происходит с другими изменяемыми типами, такими как списки:

>>> x = list('abc')
>>> y = x
>>> x
['a', 'b', 'c']
>>> y
['a', 'b', 'c']
>>> x += ['d']
>>> x
['a', 'b', 'c', 'd']
>>> y
['a', 'b', 'c', 'd']

Оказывается, что для расширенных выражений присваивания, Python пытается использовать операцию на месте всякий раз, когдавозможный :

Расширенное выражение присваивания, такое как x + = 1, может быть переписано как x = x + 1 для достижения аналогичного, но не совсем равного эффекта. В расширенной версии x оценивается только один раз. Кроме того, когда это возможно, фактическая операция выполняется на месте, а это означает, что вместо создания нового объекта и назначения его цели, вместо этого изменяется старый объект.

1 голос
/ 27 октября 2019

|= фактически вызывает update метод, см. https://docs.python.org/3/library/stdtypes.html?highlight=set#frozenset.update Вот почему он изменяет набор

...