Как хранятся переменные в Python ? Представим себе такой язык программирования как С. В языке С когда мы создаем 2 переменные каждой из которых присваивается значение 5, то это значение скопировано в ячейку память и когда мы изменяем значение этой переменной, то только оно и меняется, для конкретной переменной.
Каждая переменная хранит 101 в бинарном виде, то есть 4 + 0 + 1 = 5
int a = 5
int b = 5
# variable location value
# a 0x3E8 101
# b 0x3E9 101
Меняем значения переменной на 6
, тогда происходит изменение
значения в ячейке памяти, не затрагивая другие переменные.
int a = 6
int b = 5
# variable location value
# a 0x3E8 110
# b 0x3E9 101
Таким образом в языке Си есть именно переменные которые хранят значения и изменение значения конкретной переменной сказывается именно на ней.
В питоне, в отличии, от языка Си нет переменных, есть имена
,
ссылки
и обьекты
объекты хранят в себе сами значения, множество
имен при помощи ссылок указывают на объекты, таким образом мы можем
иметь множество различных имен каждый из которых будет указывать
на один и тот же объект.
Подсчет ссылок, питон хранит в себе не только само значение, но и постоянно подсчитывает количество имен которые ссылаются на это значение, это и есть подсчет ссылок.
Что делает питон, для простых объектов таких как строки и числа, питон создает само значение, а потом для оптимизации работы, не создает новые значения для переменной, в место этого оставляет значение не тронутым, а новому имени дает ссылку на этот уже имеющийся объект.
x = 300
y = 300
z = [300, 300]
print('x : ', id(x))
print('y : ', id(y))
print('z[0] : ', id(z[0]))
print('z[1] : ', id(z[1]))
print('x == y : ', x == y)
print('x is y : ', x is y)
# Вывод
# x : 139707576465360
# y : 139707576465360
# z[0] : 139707576465360
# z[1] : 139707576465360
# x == y : True
# x is y : True
То есть создав переменную x и дав ей значение 300
, питон создает
значение 300
и направляет ссылку переменной x
на это значение.
В этот момент счетчик ссылок для значения 300 увеличивается на +=1
когда мы создаем еще одну переменную y
счетчик увеличивается на
+=1
так образ у нас есть 2 ссылки на одно и то же значение, по
этому функция id()
которая указывает на уникальное место в памяти
для обеих переменных выдает одинаковый результат, также сравнение
по ссылке при помощи оператора is
дает True, ибо это один и тот
же объект в памяти.
Даже когда мы определим список, то есть не простой объект
z = [300, 300]
его элементы ссылаются на значение 300
,
так что это тоже является ссылками на значение 300
и количество
ссылок уже равняется 4.
Когда мы присваиваем переменным другие значения, скажем:
x = True
y = None
del z
То тем самым мы уменьшаем количество ссылок на значение 300
до
нуля, оператор del
удаляет не значение 300
, а удаляет имя
переменной z
как ссылку на значение 300
, таким образом и
уменьшаем количество ссылок на значение 300
.
В питоне каждый объект содержит в себе 3 элемента:
type: int | Тип хранящегося значения
ref-counter: 4 | Количество ссылок
value: 300 | Само значение