Определяем типы данных в Python. Изменяемые и неизменяемые типы | OTUS

Определяем типы данных в Python. Изменяемые и неизменяемые типы

В этой статье мы поговорим, как определить тип переменной в Python. Заодно, расскажем, почему одни переменные считают изменяемыми, а другие нет. И какие тут существуют тонкости, связанные с терминологией.

В некоторых случаях нужно определить тип данных переменной в Python. Проверить, к какому типу принадлежит та или иная переменная, можно посредством функции type:

>>> a = 10
>>> b = [1,2,3]
>>> type(a) == int
True
>>> type(b) == list
True
>>> type(a) == float
False

Также мы можем определить тип данных переменной в Python посредством функции isinstance():

>>> isinstance(a,int)
True
>>> isinstance(b,list)
True
>>> isinstance(b,tuple)
False
>>> c = (4,5,6)
>>> isinstance(c,tuple)
True

Здесь стоит обратить внимание, что isinstance() в отличие от type даёт возможность проверять тип данных на принадлежность хотя бы одному типу из кортежа, который передан в качестве 2-го аргумента:

>>> isinstance(a,(float, int, str))
True
>>> isinstance(a,(list, tuple, dict))
False

Также следует упомянуть и другое, не менее значимое достоинство isinstance() — поддержка наследования. Для isinstance() экземпляр производного класса является экземпляром его базового класса:

>>> class A (list):
...     pass
...
>>> a = A()
>>> type(a) == list
False
>>> type(a) == A
True
>>> isinstance(a,A)
True
>>> isinstance(a,list)
True

Проверка типов

Есть и ещё кое-что: во время преобразования типов данных переменных в Python нередко возникают следующие ошибки:

In [1]: int('a')
------------------------------------------------------
ValueError           Traceback (most recent call last)
<ipython-input-42-b3c3f4515dd4> in <module>()
----> 1 int('a')

ValueError: invalid literal for int() with base 10: 'a'

Впрочем, ошибка является вполне логичной, ведь мы пробуем преобразовать в десятичный формат строку „a“.

Понятно, что на практике вы с такой ошибкой не столкнётесь. Однако бывает, что надо, к примеру, пробежаться по списку строк, преобразовав в числа те, которые уже содержат числа. Чтобы ошибки избежать, нужно сначала определить, с каким типом переменных мы имеем дело.

В Python соответствующие средства, конечно, имеются. К примеру, используя метод isdigit(), мы определим, состоит ли наша строка из одних только цифр:

In [2]: "a".isdigit()
Out[2]: False

In [3]: "a10".isdigit()
Out[3]: False

In [4]: "10".isdigit()
Out[4]: True

Есть и ещё один метод — isalpha(). Он проверит, состоит ли наша строка из одних лишь букв:

In [7]: "a".isalpha()
Out[7]: True

In [8]: "a100".isalpha()
Out[8]: False

In [9]: "a--  ".isalpha()
Out[9]: False

In [10]: "a ".isalpha()
Out[10]: False

А вот isalnum() определит, состоит ли наша строка из цифр или букв:

In [11]: "a".isalnum()
Out[1]: True

In [12]: "a10".isalnum()
Out[12]: True

Но давайте снова вернёмся к упомянутой в начале статьи функции type. Порой, в зависимости от результата, функция или библиотека может выводить различные типы объектов. К примеру, если объект только один, то возвращается строка, а если их несколько, то нам возвращается кортеж. Мы же хотим построить ход программы по иному, с учётом того, что было возвращено: строка либо кортеж. И здесь как раз и пригодится type:

In [13]: type("string")
Out[13]: str

In [14]: type("string") is str
Out[14]: True

То же самое и с кортежем, и с иными типами данных:

In [15]: type((1,2,3))
Out[15]: tuple

In [16]: type((1,2,3)) is tuple
Out[16]: True

In [17]: type((1,2,3)) is list
Out[17]: False

Неизменяемые и изменяемые данные в Python

Считается, что все типы данных в языке программирования Python можно отнести к любой из двух категорий: — изменяемые (mutable); — неизменяемые (unmutable).

И многие из предопределённых типов являются типами неизменяемых объектов: — символьные строки (class 'str'); — числовые данные (int, float, complex); — кортежи (tuple).

Что касается других типов, то они определены как изменяемые: — множества (set), — списки (list), — словари (dict).

Кроме того, вновь определяемые пользователем классы (типы) тоже можно определить как изменяемые или неизменяемые. И вообще, изменяемость объектов какого-нибудь типа считается принципиально значимой характеристикой, которая определяет, способен ли объект такого типа выступать в виде ключа для словарей (dict) либо нет.

И тут есть один интересный нюанс, связанный с самой терминологией «изменяемый-неизменяемый» (именно она используется в русскоязычном переводе). На самом деле, такой вариант названия не совсем удачный, он вносит неоднозначность. Здесь скорее бы подошёл термин «мутирующий-немутирующий», т. к. он лучше отображает суть происходящего. А суть заключается в том, способен ли объект данного типа менять свою структурность?

К примеру строка s = 'abcdef' относится к неизменяемому типу, ведь в Python нельзя (это вам не C/C++) поменять какой-нибудь одиночный символ в строке, допустим, через s[ 2 ] = 'z', и это не говоря о том, чтобы вставить символ внутрь строки. Однако мы можем сделать s = s[ :2 ] + 'z' = s[ 3: ] и получить в итоге нужную строку 'abzdef', но это будет абсолютно другая строка, размещённая по абсолютно другому адресу в памяти, то есть s — переустановленная ссылка на новую строку. Однако поменять строку либо её длину (структурность) по текущей ссылке нельзя. В этом, как раз, и заключается неизменяемость объекта — неконстантность, ведь его значение поменять можно, однако это уже будет ссылка на другой объект с новым значением.

На этом всё, если хотите прокачать навыки Python-программирования "по-врослому", записывайтесь на курсы в OTUS:

При подготовке статьи использовались следующие материалы:

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто