Почему строки Python и кортежи сделаны неизменяемыми? - PullRequest
48 голосов
/ 08 октября 2009

Я не уверен, почему строки и кортежи были сделаны неизменяемыми; Каковы преимущества и недостатки их неизменности?

Ответы [ 6 ]

72 голосов
/ 27 октября 2009

Представьте себе язык под названием FakeMutablePython, в котором вы можете изменять строки, используя списки и т. Д. (Например, mystr[0] = 'a')

a = "abc"

Это создает запись в памяти по адресу памяти 0x1, содержащую «abc» и идентификатор a, указывающий на нее.

Теперь, скажи, что ты делаешь ..

b = a

Это создает идентификатор b, а также указывает на тот же адрес памяти 0x1

Теперь, если строка была изменчивой, и вы изменили b:

b[0] = 'z'

Это изменяет первый байт строки, хранящейся в диапазоне от 0x1 до z. Так как здесь указывается идентификатор a, таким образом, эта строка также будет изменена, поэтому ..

print a
print b

.. будет выводить zbc

Это может привести к очень странному, неожиданному поведению. Ключи словаря были бы хорошим примером этого:

mykey = 'abc'
mydict = {
    mykey: 123,
    'zbc': 321
}

anotherstring = mykey
anotherstring[0] = 'z'

Теперь в FakeMutablePython все становится довольно странным - у вас изначально есть два ключа в словаре, «abc» и «zbc». Затем вы изменяете строку «abc» (через идентификатор anotherstring) на «zbc» таким образом, у dict есть два ключа, "zbc" и "zbc" ...

Одним из решений этой странности было бы то, что всякий раз, когда вы присваиваете строку идентификатору (или используете ее как ключ dict), она копирует строку с 0x1 по 0x2.

Это предотвращает вышесказанное, но что если у вас есть строка, которая требует 200 МБ памяти?

a = "really, really long string [...]"
b = a

Вдруг ваш скрипт занимает 400 МБ памяти? Это не очень хорошо.

Как насчет того, чтобы мы указывали на тот же адрес памяти, пока не изменим его? Копировать при записи . Проблема в том, что это может быть довольно сложно сделать ..

Вот тут и приходит неизменность. Вместо того, чтобы требовать от метода .replace() скопировать строку из памяти в новый адрес, затем изменить ее и вернуть. Мы просто делаем все строки неизменяемыми, и поэтому функция должна создать новая строка для возврата. Это объясняет следующий код:

a = "abc"
b = a.replace("a", "z")

И доказано:

>>> a = 'abc'
>>> b = a
>>> id(a) == id(b)
True
>>> b = b.replace("a", "z")
>>> id(a) == id(b)
False

(функция id() возвращает адрес памяти объекта)

31 голосов
/ 08 октября 2009

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

Другое - строки в Python. считаются "элементальными", так как номера. Никакая активность изменить значение 8 на что-нибудь еще, а в Python нет активности изменит строку «восемь» на что-нибудь еще.

http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

10 голосов
/ 08 октября 2009

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

4 голосов
/ 02 июля 2010

Неизменяемые типы концептуально намного проще, чем изменяемые. Например, вам не нужно связываться с конструкторами копирования или константностью, как в C ++. Чем больше типов являются неизменяемыми, тем легче становится язык. Таким образом, самые простые языки - это чисто функциональные языки без какого-либо глобального состояния (потому что лямбда-исчисление намного проще, чем машины Тьюринга, и одинаково мощный), хотя многие люди, похоже, не ценят это.

3 голосов
/ 31 мая 2012

Perl имеет изменяемые строки и работает нормально. Вышеизложенное выглядит как много размахивание руками и рационализация для произвольного решения дизайна.

Мой ответ на вопрос, почему у Python неизменные строки, потому что создатель Python Гвидо ван Россум хотел именно этого, и теперь у него есть легионы поклонников, которые будут защищать это произвольное решение до умирающего дыхания.

Вы могли бы задать аналогичный вопрос о том, почему в Perl нет неизменяемых строк, и целая куча людей напишет, насколько ужасна сама концепция неизменяемых строк и почему это Perl The Best Bestest Idea Ever (TM), которого нет в Perl. у них есть.

3 голосов
/ 08 октября 2009

плюсов: производительность

минусы: вы не можете изменять изменяемые файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...