Не являются ли строки Python неизменяемыми? Тогда почему работает + “” + b?

Мое понимание заключалось в том, что строки Python неизменяемы.

Я попробовал следующий код:

a = "Dog" b = "eats" c = "treats" print a, b, c # Dog eats treats print a + " " + b + " " + c # Dog eats treats print a # Dog a = a + " " + b + " " + c print a # Dog eats treats # !!! 

Должен ли Python предотвратить задание? Я, вероятно, что-то пропустил.

Есть идеи?

Сначала указана на строку «Собака». Затем вы изменили переменную a чтобы указать на новую строку «Dog ест лечения». Вы на самом деле не мутировали строку «Собака». Строки неизменяемы, переменные могут указывать на то, что они хотят.

Строковые объекты сами по себе неизменяемы.

Переменная a , которая указывает на строку, изменена.

Рассматривать:

 a = "Foo" # a now points to "Foo" b = a # b points to the same "Foo" that a points to a = a + a # a points to the new string "FooFoo", but b still points to the old "Foo" print a print b # Outputs: # FooFoo # Foo # Observe that b hasn't changed, even though a has. 

Переменная a указывает на объект «Собака». Лучше всего рассматривать переменную в Python как тег. Вы можете переместить тег на разные объекты, что вы сделали, когда вы изменили a = "dog" на a = "dog eats treats" .

Однако неизменность относится к объекту, а не к тегу.


Если вы попробовали a[1] = 'z' чтобы сделать "dog" в "dzg" , вы получите ошибку:

 TypeError: 'str' object does not support item assignment" 

потому что строки не поддерживают назначение элемента, поэтому они неизменяемы.

Переменная – это просто метка, указывающая на объект. Объект неизменен, но вы можете сделать метку точкой для совершенно другого объекта, если хотите.

Что-то изменяет только тогда, когда мы можем изменять значения, хранящиеся в памяти, без изменения самой ячейки памяти.

Трюк: если вы обнаружите, что расположение памяти до и после изменения одинаково, оно изменено.

Например, список изменен. Как?

 >> a = ['hello'] >> id(a) 139767295067632 # Now let's modify #1 >> a[0] = "hello new" >> a ['hello new'] Now that we have changed "a", let's see the location of a >> id(a) 139767295067632 so it is the same as before. So we mutated a. So list is mutable. 

Строка неизменна. Как мы это докажем?

 > a = "hello" > a[0] 'h' # Now let's modify it > a[0] = 'n' ---------------------------------------------------------------------- 

мы получаем

TypeError: объект ‘str’ не поддерживает назначение элемента

Таким образом, мы не смогли изменить строку. Это означает, что строка является неизменной.

При переназначении вы изменяете переменную, указывая на новое местоположение. Здесь вы не мутировали строку, а мутировали сама переменная. Следующее – это то, что вы делаете.

 >> a = "hello" >> id(a) 139767308749440 >> a ="world" >> id(a) 139767293625808 

id до и после переназначения отличается, поэтому это доказывает, что вы на самом деле не мутируете, но указываете переменную на новое местоположение. Что не мутирует эту строку, но мутирует эту переменную.

 l = [1,2,3] print id(l) l.append(4) print id(l) #object l is the same a = "dog" print id(a) a = "cat" print id(a) #object a is a new object, previous one is deleted 

Утверждение a = a + " " + b + " " + c может быть разбито на основе указателей.

a + " " говорит мне, какие точки, которые нельзя изменить, и добавьте " " к моему текущему рабочему набору».

Память:

 working_set = "Dog " a = "Dog" b = "eats" c = "treats" 

+ b говорит, дайте мне то, на что указывает b , которое нельзя изменить, и добавьте его в текущий рабочий набор.

Память:

 working_set = "Dog eats" a = "Dog" b = "eats" c = "treats" 

+ " " + c добавляет " " к текущему набору. Затем дайте мне то, что c указывает, которое нельзя изменить, и добавьте его в текущий рабочий набор. Память:

 working_set = "Dog eats treats" a = "Dog" b = "eats" c = "treats" 

Наконец, a = говорит, что мой указатель указывает на результирующий набор.

Память:

 a = "Dog eats treats" b = "eats" c = "treats" 

"Dog" исправлена, потому что больше нет указателей, связанных с ее куском памяти. Мы никогда не изменяли раздел памяти "Dog" в котором находилось неизменное. Однако мы можем изменить, какие метки, если таковые имеются, указывают на этот раздел памяти.

Существует разница между данными и меткой, с которой она связана. Например, когда вы делаете

 a = "dog" 

данные "dog" создаются и помещаются под этикеткой a . Метка может измениться, но то, что в памяти, не будет. Данные "dog" все еще будут существовать в памяти (пока сборщик мусора не удалит его) после того, как вы это сделаете

 a = "cat" 

В вашей программе теперь ^ указывает на "cat" но строка "dog" не изменилась.

Рассматривать:

 >>> a='asdf' >>> a.__repr__  >>> a='asdf' >>> a.__repr__  >>> a='qwer' >>> a.__repr__  

Обратите внимание, что ячейка шестнадцатеричной памяти не изменилась, когда я дважды сохранил одно значение в переменной. Это изменилось, когда я сохранил другое значение. Строка неизменна. Не из-за фанатизма, а потому, что вы платите за штраф за создание нового объекта в памяти. Переменная a – это только метка, указывающая на адрес этой памяти. Его можно изменить, чтобы указать на что угодно.

Строки Python неизменяемы. Однако a не является строкой: это переменная со строковым значением. Вы не можете мутировать строку, но можете изменить значение переменной для новой строки.

Переменные могут указывать на то, что они хотят. Ошибка вызывается, если вы выполните следующее:

 a = "dog" print a #dog a[1] = "g" #ERROR!!!!!! STRINGS ARE IMMUTABLE 

>>> a = 'dogs'

>>> a.replace('dogs', 'dogs eat treats')

'dogs eat treats'

>>> print a

'dogs'

Неизменяемый, не так ли ?!

Часть изменения переменных уже обсуждалась.

Рассмотрим это дополнение к вашему примеру

  a = "Dog" b = "eats" c = "treats" print (a,b,c) #Dog eats treats d = a + " " + b + " " + c print (a) #Dog print (d) #Dog eats treats 

Одно из более точных объяснений, которые я нашел в блоге:

В Python (почти) все является объектом. То, что мы обычно называем «переменными» в Python, более правильно называют именами. Аналогично, «присваивание» на самом деле является связыванием имени с объектом. Каждая привязка имеет область видимости, обычно определяющую ее видимость, обычно это блок, в котором происходит имя.

Например:

 some_guy = 'Fred' # ... some_guy = 'George' 

Когда мы позже скажем some_guy = ‘George’, строковый объект, содержащий «Fred», не изменяется. Мы только что изменили привязку имени some_guy. Однако мы не изменили ни строковые объекты «Фред», ни «Джордж». Насколько нам известно, они могут жить бесконечно.

Ссылка на блог: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

Добавление немного больше к вышеупомянутым ответам.

id переменной изменяется при переназначении.

 >>> a = 'initial_string' >>> id(a) 139982120425648 >>> a = 'new_string' >>> id(a) 139982120425776 

Это означает, что мы изменили переменную a на новую строку. Теперь существуют два объекта string (str):

'initial_string' с id = 139982120425648

а также

'new_string' с id = 139982120425776

Рассмотрим приведенный ниже код:

 >>> b = 'intitial_string' >>> id(b) 139982120425648 

Теперь b указывает на 'initial_string' и имеет тот же id что a раньше, до переназначения.

Таким образом, 'intial_string' не был мутирован.

Подводя итог:

 a = 3 b = a a = 3+2 print b # 5 

Не является неизменным:

 a = 'OOP' b = a a = 'p'+a print b # OOP 

Неизменный:

 a = [1,2,3] b = range(len(a)) for i in range(len(a)): b[i] = a[i]+1 

Это ошибка в Python 3, потому что она неизменна. И не ошибка в Python 2, потому что явно она не является неизменной.

Вы можете сделать массив numpy неизменным и использовать первый элемент:

 numpyarrayname[0] = "write once" 

тогда:

 numpyarrayname.setflags(write=False) 

или

 numpyarrayname.flags.writeable = False 

Строковые объекты Python неизменяемы. Пример:

 >>> a = 'tanim' >>> 'Address of a is:{}'.format(id(a)) 'Address of a is:64281536' >>> a = 'ahmed' >>> 'Address of a is:{}'.format(id(a)) 'Address of a is:64281600' 

В этом примере мы видим, что когда мы назначаем другое значение в a, оно не изменяется. Создается новый объект.
И он не может быть изменен. Пример:

  >>> a[0] = 'c' Traceback (most recent call last): File "", line 1, in  **TypeError**: 'str' object does not support item assignment 

Произошла ошибка.

«mutable» означает, что мы можем изменить содержимое строки, «неизменный» означает, что мы не можем добавить дополнительную строку.

щелкните для подтверждения фотографии

  • Добавить значения в строку запроса
  • String.Format не работает в TypeScript
  • Получить переменную по имени из строки
  • Обращение строки в C
  • Выключение строки C ++
  • Ява. Игнорировать акценты при сравнении строк
  • Изменение строковых констант?
  • Что подразумевается под неизменным?
  • Как работает расширение параметра Bash?
  • ef4 причина Циркулярная ссылка в веб-службе
  • Строка для enums в C ++
  • Interesting Posts

    Обновите только одну версию XP до Windows 8 на компьютере с двойной загрузкой

    Не удается удалить определенные шрифты в Windows 7

    Как очистить БД в герою

    Как обмениваться фотографиями между двумя MacBook Pro по беспроводной сети?

    Каковы потенциальные опасности при использовании boost :: shared_ptr?

    Облачные функции для Firebase – учетная запись не настроена

    Multi-boot: Windows 10 не может видеть один диск ntfs

    Как я могу измерить время процессора и время настенных часов на Linux / Windows?

    Является ли компилятор C # достаточно умным, чтобы оптимизировать этот код?

    Итерация над запечатанной чертой в Скала?

    Есть ли использование unique_ptr с массивом?

    «Ошибка раздувания fragmentа classа» с помощью google map

    Существует ли многопользовательское приложение для удаленного рабочего стола для Mac OS X?

    Является ли `long` гарантией быть как минимум 32 бит?

    Как остановить Windows 8 от необходимости сканирования и восстановления диска при каждой загрузке

    Давайте будем гением компьютера.