Изменяемые и неизменяемые типы данных в Python

Spread the love

Оригинальная статья: BobMutable vs Immutable Data Types in Python

Задумывались ли вы, почему в Python есть изменяемые и неизменяемые типы?

Вы когда-нибудь сталкивались с подобной ошибкой в Python?

>>> s = 'hello'
>>> s[0] = 'H'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment


В этой статье я приведу несколько практических примеров и покажу некоторые преимущества использования неизменяемых типов.

Типы

Согласно справочнику по языку Python, раздел Модель данных:

Значение некоторых объектов может измениться. Объекты, чье значение может измениться, называются изменяемыми; объекты, значение которых неизменяемо после их создания, называются неизменяемыми … Изменчивость объекта определяется его типом; например, числа, строки и кортежи неизменны, а словари и списки изменчивы.

Давайте посмотрим на некоторые примеры.

Создание строки String

Когда я начал изучать Python, меня не слишком волновало как происходит конкатенации строк. Я часто использовал длинные цепочки строительного кода типа такого:

>>> s = 'hello'
>>> s += 'world'
>>> s += ...


Однако, если мы посмотрим на id каждой строки во время создание всего предложения мы увидем:

>>> s = 'hello'
>>> id(s)
4341555696
>>> s += 'world'
>>> id(s)
4341545584  => new object created!


Видно на каждом этапе создание предложения создается новая строка. Что может быть иногда не эффективно с точки зрения производительности. Возможно в подобной ситуации предпочтительно использовать изменяемый тип (например список):

>>> l = ['hello']
>>> id(l)
4341463496
>>> l.append('world')
>>> id(l)
4341463496  => same object


Использование списков в данной ситуации будет обходится дешевле с точки зрения производительности, потому что вы можете изменить размер объекта на лету.

С другой стороны, размер неизменяемых типов заранее известен в памяти, что делает их более быстрыми во время доступа к ним (Более подробное можно почитать тут: Кортежи имеют тенденцию работать лучше, чем списки — Tuples tend to perform better than lists).

Неизменность

Еще одним преимуществом неизменяемых типов является гарантия того, что эти объекты никогда не изменятся.

Изменяемые типы могут неожиданно быть изменены где-либо в вашей программе:

>>> l
['hello', 'world']
>>> ll = l  # где-то была сделана shallow копия
>>> l[0] = 'spam'
>>> l
['spam', 'world']
>>> ll
['spam', 'world']  # Опс, не преднамеренное поведение!


Или вот еще несколько коварных проблем:

Дальнейшее чтение: 5 Benefits of Immutable Objects Worth Considering for Your Next Project

Небольшое дополнение

Обратите внимание, что неизменность иногда не гарантируется на 100%. Например, вы можете иметь кортеж со списком внутри него:

>>> a = (1, [2, 3], 4)
>>> a[0] = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a[1].append(3.5)
>>> a
(1, [2, 3, 3.5], 4)


Просто нужно с осторожностью относиться.

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

Исследуя немного больше, я наткнулся на статью Лучано Рамальо «Python tuples: immutable but potentially changing», которая интересна в этом контексте:

Неизменным является физическое содержимое кортежа, состоящее только из ссылок на объекты. Значение списка, на который ссылается допустим некий список dum[1], может изменится, но идентификатор объекта, на который ссылаются, будет все тот же. У кортежа нет способа предотвратить изменение значений его элементов, которые являются независимыми объектами и могут быть доступны через ссылки вне кортежа. Списки и другие изменяемые объекты внутри кортежей могут изменяться, но их идентификаторы всегда будут одинаковыми.


React и функциональное программирование

Да, давайте немного перейдем к JS. Если вы хотите узнать больше о парадигмах неизменяемости и функционального программирования, интересно взглянуть на React:

Проще проверить, равны ли два объекта, если они неизменны, и React использует эту концепцию для оптимизации производительности.

Более подробно: Master the JavaScript Interview: What is Functional Programming?

Функциональный код имеет тенденцию быть более лаконичным, более предсказуемым и более простым для тестирования, чем императивный или объектно-ориентированный код, но если вы не знакомы с ним и общими шаблонами, связанными с ним, функциональный код также может показаться более сложным, и документация по нему может быть непроницаемой для новичков.


Я надеюсь, что это статья обратит ваше внимание на изменяемые и неизменяемые типы данных и что это значит для вашего кода …

Сохраняйте спокойствие и пишите код на Python!

— Bob

Была ли вам полезна эта статья?
[13 / 4.7]

Spread the love
Подписаться
Уведомление о
guest
2 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Анонимно
Анонимно
4 лет назад

спасибо, статья была полезной

Анонимно
Анонимно
2 лет назад

Четко, понятно. Спасибо.