Найти в Дзене
Еще один курс о Python

Что происходит, когда мы создаём переменную в Python?

Как это происходит и как работает

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

Итак. Давайте начнем с того, что девиз языка Python гласит “Все есть объект”. Это значит, что любая сущность, с которой мы можем взаимодействовать – структура данных, функция, файл, – является объектом. Исключениями здесь являются только ключевые слова(например, if, in, try и подобные), которые, очевидно, не являются объектами – да и взаимодействовать мы с ними не можем, и переменные. Думаю, это важно для понимания – в Python переменные объектами не являются.

Во-первых, переменная не хранит ни значение, ни тип. Как мы знаем, Python – язык динамической типизации, поэтому переменная не властна над типом данных, который мы хотим ей присвоить. Переменная – лишь ссылка на объект. Ничего больше. Переменной неизвестно, на какой объект она ссылается, какого он типа и какого значения.

Можем считать, что переменные хранятся в отдельном хранилище переменных в формате “переменная – ссылка на объект”. Отчасти это является причиной неожиданного поведения списка внутри кортежа – об этом я, пожалуй, напишу отдельную статью.

Итак, давайте перейдем непосредственно к теме статьи – что происходит, когда мы создаём переменную в Python и присваиваем ей значение? Можно было бы начать с того, что в этот момент Python выделяет память под новый объект, и создает его. Но это не совсем правильно – дело в том, что многие объекты Python создает в самом начале запуска программы еще до того, как произведет импорт библиотек и доберется до нашего кода. Этими объектами являются числа, близкие к нулю. Например, объект int со значением 0 или 1 Python создает всегда, даже если вы не описываете их в коде. Происходит это в самом старте программы, и необходимо для оптимизации.

Для простоты можем считать, что числа в масштабе тысячи (от -1000 до 1000) интерпретатор Python создает автоматически. Этот диапазон меняется от версии к версии языка, и знать точные его границы не обязательно – важно только помнить про этот факт.

Значит, когда мы создаем переменную, Python либо создает новый объект, либо использует уже имеющийся. Затем в хранилище переменных Python создает непосредственно переменную. Но сначала он проверяет, что такой переменной еще не было. Если она уже существует, то в уже имеющуюся переменную интерпретатор записывает ссылку на нужный объект. Если такой переменной еще нет – то она создается, и так же ей присваивается ссылка на объект.

Из книги "Как устроен Python"
Из книги "Как устроен Python"

А что, если мы сейчас создадим вторую переменную, и присвоим ей то же самое значение, что имеет первая переменная? Абсолютно не проблема. Сначала Python проверит, что такой объект уже существует, и возьмет ссылку на него. Затем аналогичным образом будет создана новая переменная, и в неё будет помещена ссылка на имеющийся объект.

Кстати, в Python есть встроенный механизм подсчета ссылок, и мы в любой момент можем проверить, сколько переменных ссылаются на объект. Для этого можно воспользоваться методом getrefcount() из библиотеки sys. Например:

In [1]: import sys
In [2]: a = 'count me'
In [3]: b = a
In [4]: sys.getrefcount(a)
Out[4]: 3

Правда, есть особенность – getrefcount() возвращает число ссылок + 1, поскольку сам создает временную ссылку для подсчета :)

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

Если вам понравилась статья, рекомендую почитать другие мои статьи, например, про то, как работает функция len() или как быстро работает встроенная сортировка sorted()

Если вы хотите изучать Python и погружаться в его особенности –приглашаю вас на мой курс MyFriendCourse. Вводное занятие бесплатно –заниматься можно в небольших группах или индивидуально. Я сам выдаю и проверяю домашнее задание и помогаю его решать :)