Переменные и типы данных

Переменные

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

Для создания новой переменной в Python достаточно просто присвоить ей любой значение. В дальнейшем по имени можно уже вносить другие данные. Стоит учитывать, что при сохранении нового значения, старые данные безвозвратно теряются.

Операцию занесения новых данных принято называть присваиванием. Для этого используется привычный оператор присваивания =. В левой части находится переменная, в правой части – новое значение.

Для извлечения текущего значения достаточно просто указать имя переменной.

>>> # Выводим результат сложения числа из переменной n и 221
>>> print(n + 221)
434

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

Также в качестве имени запрещено использовать ключевые слова, которые уже используются в Python для различных языковых конструкций. Для вывода всех ключевых слов можно использовать следующий код:

>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

Также рекомендуется избегать совпадений с внутренними идентификаторами (функции, модули, классы и так далее). Для получения списка идентификаторов также лучше использовать готовую команду:

>>> import builtins
>>> print(dir(builtins))

Пример корректных переменных: n, s4, author, name_users.

Неправильный формат: 1d, !count, global.

Также важно помнить, что Python учитывает регистр букв в именах переменных. К примеру, y и Y – будут восприниматься как разные переменные. Для демонстрации можно использовать следующий набор:

>>> x = 20; X = 30
>>> print(x, X)
20 30

Типы данных. Понятие объекта и ссылки

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

int – целое число. Размер ограничен только доступным объемом ОЗУ. В примерах ниже будет использоваться функция type(), которая позволяет вывести тип переменной или значения:

>>> type(2146483347)
(<class 'int'>)

float – вещественное (дробное) число:

>>> type(7.1), type(8.6e-3)
(<class 'float'>, <class 'float'>)

bool – логическое значение. Поддерживает только два значения – False (ложь) и True (истина):

>>> type(True), type(False)
(<class 'bool'>, <class 'bool'>)

str – строка (последовательный набор произвольных символов).

>>> type("Это простая строка")
<class 'str'>

list – список. Представляет собор набор пронумерованных значений (элементов). Есть возможность изменять, добавлять и удалять отдельные элементы.

>>> type([4, 2, 3])
<class 'list'>

При необходимости можно изменить значение отдельного элемента:

>>> l = [3, 2, 1] # Создаем список из трех чисел
>>> print(l)
    [3, 2, 1]
>>> l[1] = 40 # Изменяем второй элемент
>>> print(l)
    [3, 40, 1]

tuple – кортеж. Структура аналогична списку, но изменять кортеж нельзя.

>>> type( (1, 2, 3) )
<class 'tuple'>

При попытке явным образом внести изменения в кортеж будет выведена ошибка:

>>> t = (1, 7, 3) # Создаем кортеж из трех чисел
>>> t[2] = 40 # Пытаемся заменить третий элемент и получаем ошибку

Traceback (most recent call last):
    File "<pyshell#30>", line 1, in <module>
        t[2] = 60
TypeError: 'tuple' object does not support item assignment

set – множество. Принцип работы аналогичен списку, но сохраняются только уникальные значения.

>>> type( {"a", "b", "c"} )
<class 'set'>

range – диапазон. Представляет собой последовательность целых чисел, указывается начальное значение, конечное и шаг (по умолчанию 1).

>>> type( range(1, 10) )
<class 'range'>

bytearray – изменяемая последовательность байтов.

>>> type(bytearray("Текст", "utf-8"))
<class 'bytearray'>

bytes – неизменяемая последовательность байтов.

>>> type(bytes("Текст", "utf-8"))
<class 'bytes'>

frozenset – неизменяемое множество.

>>> type(frozenset(["a", "b", "c"]))
<class 'frozenset'>

Типы tuple, set, list, range, frozenset, bytes и bytearray принято обозначать под общим названием последовательности. Их элементы можно перебрать, например, при помощи обычного цикла, совершая над текущим элементом определенные действия. Строки также относят к последовательностям, поскольку есть возможность

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

>>> type( {"x": 7, "y": 30} )
<class 'dict'>

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

NoneType – «пустой тип». Может принимать единственное значение None, которое обозначает отсутствие «значащего» значения.

>>> type(None)
<class 'NoneType'>

function — функции:

>>> def func(): pass
...
>>> type(func)
    <class 'function'>

complex – комплексные числа:

>>> type(3+2j)
<class 'complex'>

module – модули:

>>> import sys
>>> type(sys)
    <class 'module'>

type — классы и типы данных:

>>> class C: pass
...
>>> type(C)
    <class 'type'>
>>> type(type(""))
    <class 'type'>

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

Важно помнить, что при присваивании нового значения переменной, в нее заносится не конкретное значение, а ссылка на него. Такую ссылку можно рассматривать как указатель на выбранный объект. В некоторых случаях это может приводить к неожиданному поведению переменных. К примеру, если в переменную добавить список, далее значение этой же переменной присвоить значение другой переменной, то в обоих случаях в переменной будет только ссылка на первоначальный список. Для демонстрации данной особенности можно использовать код:

>>> a = [1, 3, 5] # Присваиваем список переменной a
>>> b = a # Присваиваем значение переменной a (список) переменной b
>>> print(a, b)
[1, 3, 5] [1, 3, 5]
>>> a[1] = 40 # Изменяем второй элемент списка из переменной a
>>>           # обе переменные ссылаются на один и тот же список
>>> print(a, b) #
    [1, 40, 5] [1, 40, 5]

Глобально типы принято делить на неизменяемые и изменяемые. Ко второму типу относят list, bytearray, set и dict – можно изменить отдельный элемент последовательности. Соответственно, значение неизменяемых типов изменить нельзя.

К неизменяемым типам также относят логические величины и числа. К примеру, если в переменную занести число, далее присвоить этой же переменной другое число, интерпретатор не буде заменять исходное значение. Вместо этого будет создан новый объект, который и попадет в переменную, Старый объект при этом из памяти удаляется для оптимизации.

Присваивание значений переменным

Операция присваивания – занесение в указанную переменную нового значения. Для этого используется знак равенства – слева от него ставится переменная, справа нужное значение. Примеры:

>>> x = 7 # Присваивание целого числа (тип int)
>>> s1 = "Короткая строка" # Присваивание строки (тип string)
>>> y = 7.8 # Присваивание вещественного числа (тип float)
>>> b = True # Присваивание логической величины True (тип bool)

Поддерживается режим группового присваивания, когда значения заносятся в несколько переменных:

>>> x = y = 20 # Переменным x и y присвоено число 20
>>> print(x, y)
20 20

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

>>> x = y = [1, 7]   # якобы создано два списка
>>> print(x, y)
    [1, 7] [1, 7]
>>> y[1] = 30 # Изменяем второй элемент списка
>>> print(x, y)
    [1, 30] [1, 30]

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

>>> x = [1, 7]
>>> y = [1, 7]
>>> y[1] = 20 # Изменяем второй элемент
>>> print(x, y)
    [1, 7] [1, 20]

Предусмотрен оператор is, который позволяет проверить, ссылаются ли переменные на один объект. Если это так, оператор возвращает True, иначе – False.

>>> x = y = [1, 8] # Один объект
>>> x is y
    True
>>> x = [1, 8] # Разные объекты
>>> y = [1, 8] # Разные объекты
>>> x is y
    False

Также следует учитывать еще одну особенность работы интерпретатора Python. Для повышения производительности для небольших строк и чисел часто используется кэширование. Это означает, что есть создать, к примеру, пятьдесят переменных и присвоить им число 3, то, вероятнее всего, для данных переменных будет использоваться ссылка на один объект.

>>> x = 3; y = 3; z = 3
>>> x is y, y is z
    (True, True)

Есть возможность посмотреть количество ссылок на определенный объект – для этого используется функция getrefcount(), которая находится в модуле sys.

>>> import sys # Подключаем модуль sys
>>> sys.getrefcount(7)
204

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

Python кроме группового поддерживает и позиционное присваивание, что также позволяет сделать код более компактным. Нужное количество переменных указывается через запятую слева от оператора =, присваиваемые значения справа.

>>> x, y, z = 1, 9, 33
>>> print(x, y, z)
1 9 33

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

>>> x, y = 1, 2
>>> x, y
    (1, 2)
>>> x, y = y, x
>>> x, y
    (2, 1)

И слева и справа можно использовать последовательности, например, строки или списки.

>>> x, y, z = "456" # Строка
>>> x, y, z
    ('4', '5', '6')

>>> x, y, z = [6, 7, 8] # Список
>>> x, y, z
    (6, 7, 8)

>>> x, y, z = (3, 4, 5) # Кортеж
>>> x, y, z
    (3, 4, 5)

>>> [x, y, z] = (5, 4, 3) # Список слева, кортеж справа
>>> x, y, z
    (5, 2, 3)

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

>>> x, y, z = (1, 2, 3, 4)
    Traceback (most recent call last):
        File "<pyshell#130>", line 1, in <module>
            x, y, z = (1, 2, 3, 4)
    ValueError: too many values to unpack (expected 3)

При несоответствии количества значений и переменных Python позволяет лишние значения сохранить в отдельный список. Для этого достаточно перед именем нужной переменной поставить символ *.

>>> x, y, *z = (1, 2, 3, 4)
>>> x, y, z
    (1, 2, [3, 4])

>>> x, y, *z = (1, 2, 3)
>>> x, y, z
    (1, 2, [3])

>>> x, *y, z = (1, 2, 3, 4)
>>> x, y, z
    (1, [2, 3], 4)

>>> *x, y, z = (1, 2, 3, 4)
>>> x, y, z
    ([1, 2], 3, 4)

>>> x, y, *z = (1, 2)
>>> x, y, z
    (1, 2, [])

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



>>> *x, y, *z = (1, 2, 3, 4)
    SyntaxError: two starred expressions in assignment


Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: