При импортировании модуля math количество ссылок на объект None уменьшается

Рейтинг: 13Ответов: 2Опубликовано: 19.08.2023

Заметил интересное поведение, понять которое не могу.

При импортировании модуля math кол-во ссылок на объект None уменьшается:

import sys

print(sys.getrefcount(None))
import math
print(sys.getrefcount(None))

Вывод:

4138
4099

Стало интересно, почему так происходит. Если кто объяснит буду рад)

Ответы

▲ 6Принят

Как сказали проффесионалы:

I think this is just the method cache filling up in Python 3.8. When a cache entry gets filled, it drops a reference to None and instead holds a reference to a string.

A little printf-debugging showed this:

>>> import math
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\listobject.c:2488
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\listobject.c:2488
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\compile.c:1331
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\compile.c:1331
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:6805
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:6805
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3390
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3391
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
INCREF None
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:6805
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3390
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3391
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\typeobject.c:3160
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:4971
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2978
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2979
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\frameobject.c:430
INCREF None
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2373
INCREF None
INCREF None
INCREF None
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3390
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3391
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:1363
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\weakrefobject.c:939
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Objects\funcobject.c:585
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3390
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:3391
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\ceval.c:2995
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Include\object.h:560
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\pythonrun.c:268
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Modules\_io\bufferedio.c:804
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\pythonrun.c:1126
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Modules\_io\bufferedio.c:804
INCREF None
DECREF None at C:\Users\sween\Source\Repos\cpython2\cpython\Python\pythonrun.c:1134

Перевод:

Я думаю, что это просто заполнения кэша методов в Python 3.8. Когда запись кэша заполняется, она удаляет ссылку на None и вместо этого содержит ссылку на строку.

Небольшой отладочный printf показал это:

-- обрезано --

То есть дело в том что math не хватает кэша методов (method cache) и он удаляет оттуда лишние None.

▲ 3

я конечно не знаток, но мне кажется что для math надо много памяти, а None самый ненужный оператор. попробуй создать функцию, после импорта math, и ссылки опять уменьшатся.

import sys

print(sys.getrefcount(None))
import math
print(sys.getrefcount(None))
def no():
    pass
print(sys.getrefcount(None))