В Python A
не эквивалентен как a + b
Анкет Они не ведут себя всегда. Рассмотрим следующее:
>>> a = [1, 2, 3] >>> b = a >>> a += [4, 5, 6] >>> a [1, 2, 3, 4, 5, 6] >>> b [1, 2, 3, 4, 5, 6]
>>> a = [1, 2, 3] >>> b = a >>> a = a + [4, 5, 6] >>> a [1, 2, 3, 4, 5, 6] >>> b [1, 2, 3]
Что здесь случилось:
A
изменил список на месте. Это означает, что он расширился A тако, что A а также b имел ссылку на тот же список.a + b
Выражение создало новый список и изменил A Ссылка на этот новый список. И b ссылается на старый список. Почему это случилось? Вот как реализует Python+
и+=
операторы. Когда вы используете+
Оператор Python вызывает__add__
Специальный метод. С другой стороны+=
Оператор вызывает__iADD__
Специальный метод, и если__iADD__
недоступен только тогда, когда он использует__add__
метод Смотри ниже:
class MyList (list): def __add__ (self, other): print ("__add__ has been called") return super (MyList, self).__add__ (other) def __iadd__ (self, other): print ("__iadd__ has been called") return super (MyList, self).__iadd__ (other)
Теперь запустите приведенный ниже код:
a = MyList ([1, 2, 3]) b = a a = a + b
Это дает следующий вывод:
__add__ has been called
Теперь запустите приведенный ниже код:
a = MyList ([1, 2, 3]) b = a a += b
Это дает следующий выход:
__iadd__ has been called
__iADD__
Специальный метод предназначен для дополнения. То есть он мутирует объект, на который он действует (в A
__iADD__
мутает A ) С другой стороны, __add__
Метод возвращает новый объект (в a + b
Мы назначили возвращаемый объект __add__
__iADD__
доступен только для изменчивых типов. Вот почему для неизменных типов, таких как целые числа ( int
), строки ( str
) и кортеж
оба +
и +=
эквивалентны, поскольку они оба вызывают __add__
Анкет И это то, что позволяет вам использовать +=
на неизменных типах.
Теперь давайте посмотрим еще одну разницу между +
и +=
Анкет Рассмотрим следующее:
>>> a = [1, 2, 3] >>> b = "hello" >>> a + b TypeError: can only concatenate list (not "str") to list >>> a += b >>> a [1, 2, 3, 'h', 'e', 'l', 'l', 'o']
Здесь a + b
дает TypeError
Анкет Потому что +
Оператор симметричен. Итак, мы не можем добавить список
и str
Анкет Но +=
Оператор, очевидно, не симметричен. Это эквивалентно List.extend
, который итерации над вторым операндом. Смотри ниже:
class MyStr (str): def __iter__ (self): print ("__iter__ has been called") return super (MyStr, self).__iter__() a = [1, 2, 3] b = "hello" a += b
Это дает следующий вывод:
__iter__ has been called
Итак, для типов, которые поддерживают оба __add__
и __я добавить__
Поэтому вы должны быть осторожны, какой из них вы используете.
Оригинал: “https://dev.to/tahmid02016/a-b-is-not-the-same-as-a-a-b-4ekc”