Почему python хранит эти две переменные в одном месте? - PullRequest
1 голос
/ 08 июля 2020

Рассмотрим следующий код:

x = 50000000
y = 50000000

print(hex(id(x)), hex(id(y)))
print(x is y)

Это дает:

0x23ef28ec930 0x23ef28ec930
True

Теперь я пришел к выводу, что для небольших значений python использует оптимизацию для кэширования их в памяти. Но это число явно больше, чем это значение, которое, как я полагаю, равно 256.

Почему нет, когда я объявляю, что они хранятся отдельно в памяти?

В дополнение к этому, если я добавлю в строке y+=1 непосредственно перед оператором печати, тогда x and y хранятся в разных местах в памяти, а x is y равно False. Я бы подумал, что, поскольку это один и тот же объект в памяти, при увеличении y увеличивается и x.

Ясно, что мне не хватает чего-то фундаментального, и я был бы признателен за его прояснение.

Еще один вопрос, зависит ли это поведение от типа переменной? А если x,y не целые числа, а списки, строки или любой другой объект?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 08 июля 2020
x = 50000000

Здесь Python создает int и сохраняет его в 0x23ef28ec930.

y = 50000000

Здесь интерпретатор смог каким-то образом определить, что это число уже существует в программе , поэтому для y используется тот же объект, что и для x. Поскольку это числовые литералы, число 50000000 могло быть сохранено во время компиляции, а затем использовано для обоих этих назначений.

Насколько мне известно, Python не дает никаких гарантий относительно идентичности неизменные значения будут иметь тот же адрес. Вы не должны полагаться на это поведение, кроме случаев, когда имеете дело с синглтонами, например None, True и False.

В дополнение к этому, если я добавлю в строку y + = 1 непосредственно перед оператор печати, то x и y хранятся в разных местах в памяти, а x is y false. Я бы подумал, что, поскольку это один и тот же объект в памяти, при увеличении y увеличивается и x.

int s неизменяемы. Когда вы выполняете y += 1, вы присваиваете новое значение y, что отличает его от x.

В дальнейшем это поведение зависит от типа переменной? А если x, y не целые числа, а списки, строки или любой другой объект?

Это во многом зависит от того, являются ли значения изменяемыми или неизменяемыми. Строки неизменяемы, поэтому идентичные могут иметь одинаковый адрес. Списки изменяемы, поэтому имеет большое значение, относятся ли x и y к одному и тому же списку или к двум вновь созданным спискам. Эти два фрагмента очень разные:

# These have different addresses. They can be changed independently.
x = []
y = []

# These variables refer to the same list.
x = []
y = x

Обратите внимание, что такие операторы, как +=, пытаются изменить объект на месте. Это, очевидно, невозможно с неизменяемыми значениями, но для списков y += [6] изменяет существующий список, а y = y + [6] создает новый список. += не всегда эквивалентно простому сложению.

0 голосов
/ 08 июля 2020

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

https://docs.python.org/2.0/ext/refcounts.html

...