Неожиданный результат от sys.getrefcount - PullRequest
5 голосов
/ 17 апреля 2009

Когда я набрал:

>>> astrd = 123
>>> import sys
>>> sys.getrefcount(astrd)
3
>>> 

Я не получаю, где astrd используется 3 раза?

Ответы [ 4 ]

7 голосов
/ 17 апреля 2009

Это не astrd, на который ссылаются три раза, а значение 123. astrd - это просто имя (неизменяемого) числа 123, на которое можно ссылаться, однако, много раз. Кроме того, обычно делятся маленькие целые числа:

>>> astrd = 123
>>> sys.getrefcount(astrd)
4
>>> j = 123
>>> sys.getrefcount(astrd)
5

Во втором присваивании новое целое число не создается, вместо этого j - это просто новое имя для целого числа 123.

Однако, учитывая очень большие целые числа, это не имеет места:

>>> i = 823423442583
>>> sys.getrefcount(i)
2
>>> j = 823423442583
>>> sys.getrefcount(i)
2

Общие целые числа являются подробностями реализации CPython (среди прочих). Поскольку маленькие целые числа создаются очень часто, их совместное использование экономит много памяти. Это стало возможным благодаря тому факту, что целые числа являются неизменными в первую очередь.

Для дополнительной ссылки во втором примере, см. ответ кодеапе .

7 голосов
/ 17 апреля 2009

Из строки документации getrefcount :

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

Две другие ссылки означают, что Python внутренне содержит две ссылки на объект. Может быть, словари localals () и globals () считаются одной ссылкой каждый?

6 голосов
/ 17 апреля 2009

Я думаю, что он считает ссылки на 123, попробуйте другие примеры, например

>>> import sys
>>> astrd = 1
>>> sys.getrefcount(astrd)
177
>>> astrd = 9802374987193847
>>> sys.getrefcount(astrd)
2
>>> 

Пересчет 9802374987193847 соответствует ответу Codeape.

Вероятно, это потому, что числа неизменны. Например, если вы используете список, он всегда будет равен 2 (из чистого приглашения).

Кстати, я тоже получаю 2 за 123, возможно, ваши настройки несколько иные? Или это может быть связано со временем или около того?

5 голосов
/ 17 апреля 2009

int реализованы особым образом, они кэшируются и делятся, поэтому вы не получаете 1.

И python, использует объекты с подсчетом ссылок. astrd сам по себе является ссылкой, поэтому вы фактически получаете количество ссылок на int '123'. Попробуйте другой (определенный пользователем) тип, и вы получите 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...