Кеширование небольших чисел в CPython
Автор: PythonInDepth
Поговорим о небольших числах в CPython. Возьмем, например, два числа, 10 и 300:
>>> a = 10 >>> b = 300 >>> a is 10 True >>> b is 300 False
Что?! Почему a указывает на свое значение, а b — нет?
Все дело в том, что интерпретатор хранит числа в диапазоне от — 5 до 256 в специальном массиве. Поэтому когда мы пишем x = 10, то вообще-то получаем ссылку на объект, который уже существует в памяти:
>>> c = 1 >>> id(1) 94492411548416 >>> id(c) 94492411548416
Причем это касается любых значений, которые приводятся к целым числам этого диапазона. Можно завести число хоть в двоичном виде, хоть в hex, кеширование все равно будет работать:
>>> id(19) 94579033949504 >>> id(0b10011) 94579033949504 >>> id(0o23) 94579033949504 >>> id(0x13) 94579033949504
Числа вне диапазона — 5, 256 интерпретатор тоже будет пытаться оптимизировать, но только если они находятся в одной строке (или одном файле). В командной строке интерпретатора так не работает:
>>> d = 400 >>> d is 400 False
а так будет:
>>> e = 500; f = 500 >>> e is f True
В общем и целом то, что нужно запомнить — это что небольшие числа в интерпретаторе хранятся не так, как большие, и что с ними следует пользоваться оператором ==, а не is.
И это снова не фича, а деталь реализации для экономии ресурсов. А пишу я об этом, потому что на задачу с кешем наткнулась на собеседовании, и собеседующий удивился, что я в курсе. Сказал, что узнал об этой особенности, когда начал сам проводить собеседования. Теперь это знаете и вы.
- Проходите тест по Python и поймите, готовы ли вы идти на курсы
- 24 views
- 0 Comment