Не являются ли строки 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 предотвратить задание? Я, вероятно, что-то пропустил.
- Формат метода (String, Object ) в типе String не применим для аргументов (...)
- Закрытие сканера вызывает java.util.NoSuchElementException
- Java разделяет строку на массив
- Сколько байтов принимает один символ Unicode?
- Получить n-й символ строки в языке программирования Swift
Есть идеи?
- Java: метод для получения позиции соответствия в String?
- Как преобразовать String в ArrayList?
- Удалить пробел из строки в Objective-C
- Как напечатать полное значение длинной строки в gdb?
- Пакет / Поиск и редактирование строк в TXT-файле
- Что рекурсивно распространяется на все файлы в текущем каталоге?
- Преобразование секретного ключа в строку и наоборот
- Конкатенация строк: оператор concat () vs "+"
Сначала указана на строку «Собака». Затем вы изменили переменную 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» означает, что мы можем изменить содержимое строки, «неизменный» означает, что мы не можем добавить дополнительную строку.