pass - python send reference




Python's Passing by References (2)

На этот вопрос уже есть ответ:

Привет, я пытаюсь понять, как работает Python по ссылке. У меня есть пример:

>>>a = 1
>>>b = 1
>>>id(a);id(b)
140522779858088
140522779858088

Это имеет смысл, так как a и b ссылаются на то же значение, что и у них. Я не совсем понимаю, как этот пример:

>>>a = 4.4
>>>b = 1.0+3.4
>>>id(a);id(b)
140522778796184
140522778796136

Отличается от этого примера:

>>>a = 2
>>>b = 2 + 0
>>>id(a);id(b)
140522779858064
140522779858064

Это потому, что в 3-м примере объект-объект 0 рассматривается интерпретатором как «Нет» и не распознается как нуждающийся в другом идентификаторе от объекта, к которому относится переменная «a» (2)? Если во втором примере «b» добавляет два разных объекта int, и интерпретатор выделяет память для обоих этих объектов, которые будут добавлены, что дает переменную «a», другую идентификацию из переменной «b»?


В первом примере имена a и b являются «ссылкой» на один и тот же объект из-за интернирования . Оператор присваивания привел к целому числу с одним и тем же id только потому, что он повторно использовал ранее существовавший объект, который уже висел в памяти. Это не надежное поведение целых чисел:

>>> a = 257
>>> b = 257
>>> id(a), id(b)
(30610608, 30610728)

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

Не думайте о «ссылке» и «значении» при работе с Python, модель, которая работает для C, здесь не работает. Вместо этого подумайте о «именах» и «объектах».

На приведенной выше диаграмме показан ваш третий пример. 2 - объект, a и b - имена. У нас могут быть разные имена, указывающие на один и тот же объект. И объекты могут существовать без какого-либо имени.

Присвоение переменной присваивает только намету . И удаление переменной только удаляет nametag . Если вы помните эту идею, то объектная модель Python никогда вас не удивит.


Как указано here , CPython кэширует целые числа от -5 до 256. Таким образом, все переменные в этом диапазоне с одинаковым значением имеют один и тот же идентификатор (я бы не стал делать ставку на это для будущих версий, но это текущая реализация)

Вероятно, нет такой вещи для поплавков, потому что существует «бесконечность» возможных значений (ну не бесконечная, но большая из-за с плавающей запятой), поэтому вероятность вычисления одного и того же значения различными способами действительно низка по сравнению с целыми числами.

>>> a=4.0
>>> b=4.0
>>> a is b
False




python-internals