Это потому, что bool
является подклассом int
в Python 2 и 3.
>>> issubclass(bool, int)
True
Но реализация int
изменился.
В Python 2 int
был 32- или 64-битным, в зависимости от системы, в отличие от произвольной длины long
.
В Python 3, int
произвольной длины - long
Python 2 был переименован в int
, а исходный Python 2 int
вообще отброшен.
В Python 2 вы получаете точно такой жеповедение для long объектов 1L
и 0L
:
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getsizeof(1L)
28
>>> sys.getsizeof(0L)
24
long
/ Python 3 int
является объектом переменной длины, так же каккортеж - когда он выделен, выделяется достаточно памяти для хранения всех двоичных цифр, необходимых для его представления.Длина переменной части хранится в заголовке объекта.0
не требует двоичных цифр (его переменная длина равна 0), но даже 1
выходит за пределы и требует дополнительных цифр.
Т.е. 0
представляется в виде двоичной строки длины 0:
<>
и 1 представлены в виде 30-битной двоичной строки:
<000000000000000000000000000001>
В конфигурации по умолчанию в Python используется 30 бит в uint32_t
;so 2**30 - 1
по-прежнему умещается в 28 байт на x86-64, а 2**30
потребует 32;
2**30 - 1
будет представлен как
<111111111111111111111111111111>
, т.е. все 30 битов значения установлены в 1;2 ** 30 потребуется больше, и у него будет внутреннее представление
<000000000000000000000000000001000000000000000000000000000000>
Что касается True
, использующего 28 байтов вместо 24 -тебе не нужно беспокоиться.True
является синглтоном , поэтому в любой программе на Python всего теряется только 4 байта, а не 4 при каждом использовании True
.